This is an automated email from the git hooks/post-receive script. New commit to branch feature/6688 in repository tutti. See http://git.codelutin.com/tutti.git commit 3d10fbcad8f320a752f7dfa26d993d2f732a6e0e Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Mar 2 16:30:30 2015 +0100 validate surey.csv file + improve validation result --- .../GenericFormatImportValidationHelper.java | 56 ++++++++++++++++++++++ .../consumer/CruiseNotValidException.java | 34 +++++-------- .../consumer/CsvConsumerForOperation.java | 5 +- .../consumer/CsvConsumerForSurvey.java | 22 +++++++-- .../FishingOperationNotValidException.java | 34 +++++-------- .../consumer/MismatchProgramException.java | 39 +++++++++++++++ .../resources/i18n/tutti-service_fr_FR.properties | 3 +- .../GenericFormatImportServiceValidTest.java | 3 +- .../genericFormat/badSurveyImport/survey.csv | 4 +- 9 files changed, 147 insertions(+), 53 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportValidationHelper.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportValidationHelper.java index 91c2bba..7bd3f5d 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportValidationHelper.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportValidationHelper.java @@ -14,8 +14,16 @@ import fr.ifremer.tutti.service.genericformat.csv.RowWithOperationContextSupport import org.apache.commons.io.IOUtils; import org.nuiton.csv.ImportRow; import org.nuiton.validator.NuitonValidatorResult; +import org.nuiton.validator.NuitonValidatorScope; import java.io.Closeable; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +import static org.nuiton.i18n.I18n.t; /** * Created on 2/19/15. @@ -37,6 +45,54 @@ public class GenericFormatImportValidationHelper implements Closeable { this.originalValidationDataContextSupport = TuttiValidationDataContextSupport.setValidationContext(validationDataContext, true); } + public static String getMessage(String prefix, Set<String> messages) { + + StringBuilder builder = new StringBuilder(prefix); + builder.append("<ul>"); + for (String message : messages) { + builder.append("<li>").append(message).append("</li>"); + + } + builder.append("</ul>"); + return builder.toString(); + + } + + public Set<String> getMessages(NuitonValidatorResult validatorResult, NuitonValidatorScope scope) { + + Set<String> result = null; + if (validatorResult.hasMessagesForScope(scope)) { + + result = new LinkedHashSet<>(); + + List<String> messagesForScope = validatorResult.getMessagesForScope(scope); + for (String message : messagesForScope) { + + String i18nError = getI18nError(message); + result.add(i18nError); + } + + } + return result; + + } + + protected String getI18nError(String error) { + String text; + if (!error.contains("##")) { + text = t(error); + } else { + StringTokenizer stk = new StringTokenizer(error, "##"); + String errorName = stk.nextToken(); + List<String> args = new ArrayList<>(); + while (stk.hasMoreTokens()) { + args.add(stk.nextToken()); + } + text = t(errorName, args.toArray()); + } + return text; + } + @Override public void close() { diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CruiseNotValidException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CruiseNotValidException.java index 15f93ff..4279a9b 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CruiseNotValidException.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CruiseNotValidException.java @@ -1,11 +1,9 @@ package fr.ifremer.tutti.service.genericformat.consumer; -import com.google.common.base.Joiner; import fr.ifremer.tutti.persistence.entities.data.Cruise; -import org.nuiton.validator.NuitonValidatorResult; -import org.nuiton.validator.NuitonValidatorScope; +import fr.ifremer.tutti.service.genericformat.GenericFormatImportValidationHelper; -import java.util.List; +import java.util.Set; import static org.nuiton.i18n.I18n.t; @@ -21,36 +19,26 @@ public class CruiseNotValidException extends Exception { private final Cruise cruise; - private final NuitonValidatorResult validatorResult; + private final Set<String> errorMessages; - public CruiseNotValidException(Cruise cruise, NuitonValidatorResult validatorResult) { + public CruiseNotValidException(Cruise cruise, Set<String> errorMessages) { this.cruise = cruise; - this.validatorResult = validatorResult; + this.errorMessages = errorMessages; } public Cruise getCruise() { return cruise; } + public Set<String> getErrorMessages() { + return errorMessages; + } + @Override public String getMessage() { - StringBuilder builder = new StringBuilder(); - - if (validatorResult.hasFatalMessages()) { - List<String> fatalMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.FATAL); - builder.append(t("tutti.fatal.messages", Joiner.on("\n-").join(fatalMessage))); - } - if (validatorResult.hasErrorMessagess()) { - List<String> errorsMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.ERROR); - builder.append(t("tutti.error.messages", Joiner.on("\n-").join(errorsMessage))); - } - if (validatorResult.hasWarningMessages()) { - List<String> warningMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.WARNING); - builder.append(t("tutti.warning.messages", Joiner.on("\n-").join(warningMessage))); - } - - String message = t("tutti.service.genericFormat.import.error.cruiseNotValid", builder.toString()); + String errors = GenericFormatImportValidationHelper.getMessage("", errorMessages); + String message = t("tutti.service.genericFormat.import.error.cruiseNotValid", errors); return message; } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForOperation.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForOperation.java index d00c78b..8065cf3 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForOperation.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForOperation.java @@ -13,8 +13,10 @@ import fr.ifremer.tutti.service.genericformat.csv.OperationRow; import org.apache.commons.lang3.BooleanUtils; import org.nuiton.csv.ImportRow; import org.nuiton.validator.NuitonValidatorResult; +import org.nuiton.validator.NuitonValidatorScope; import java.nio.file.Path; +import java.util.Set; /** * Created on 2/11/15. @@ -64,7 +66,8 @@ public class CsvConsumerForOperation extends CsvComsumer<OperationRow, Operation if (validatorResult.hasFatalMessages()) { - addCheckError(row, new FishingOperationNotValidException(fishingOperation, validatorResult)); + Set<String> errorMessages = validationHelper.getMessages(validatorResult, NuitonValidatorScope.FATAL); + addCheckError(row, new FishingOperationNotValidException(fishingOperation, errorMessages)); } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForSurvey.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForSurvey.java index 4968b75..28f47e9 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForSurvey.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/CsvConsumerForSurvey.java @@ -1,18 +1,22 @@ package fr.ifremer.tutti.service.genericformat.consumer; import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.Program; import fr.ifremer.tutti.persistence.entities.referential.GearWithOriginalRankOrder; import fr.ifremer.tutti.persistence.entities.referential.GearWithOriginalRankOrders; import fr.ifremer.tutti.service.csv.CsvComsumer; import fr.ifremer.tutti.service.genericformat.GenericFormatImportContext; import fr.ifremer.tutti.service.genericformat.GenericFormatImportEntityParserFactory; +import fr.ifremer.tutti.service.genericformat.GenericFormatImportValidationHelper; import fr.ifremer.tutti.service.genericformat.csv.SurveyModel; import fr.ifremer.tutti.service.genericformat.csv.SurveyRow; import org.nuiton.csv.ImportRow; import org.nuiton.validator.NuitonValidatorResult; +import org.nuiton.validator.NuitonValidatorScope; import java.nio.file.Path; import java.util.List; +import java.util.Set; /** * Created on 2/11/15. @@ -51,13 +55,25 @@ public class CsvConsumerForSurvey extends CsvComsumer<SurveyRow, SurveyModel> { } - NuitonValidatorResult nuitonValidatorResult = importContext.getValidationHelper().validateCruise(cruise); - if (nuitonValidatorResult.hasFatalMessages()) { + GenericFormatImportValidationHelper validationHelper = importContext.getValidationHelper(); + NuitonValidatorResult nuitonValidatorResult = validationHelper.validateCruise(cruise); + if (nuitonValidatorResult.hasErrorMessagess()) { - addCheckError(row, new CruiseNotValidException(cruise, nuitonValidatorResult)); + Set<String> errorMessages = validationHelper.getMessages(nuitonValidatorResult, NuitonValidatorScope.ERROR); + addCheckError(row, new CruiseNotValidException(cruise, errorMessages)); } + Program program = cruise.getProgram(); + if (program != null) { + + Program expectedProgram = importContext.getImportRequest().getProgram(); + if (!expectedProgram.equals(program)) { + + addCheckError(row, new MismatchProgramException(cruise, expectedProgram)); + } + } + } } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/FishingOperationNotValidException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/FishingOperationNotValidException.java index f159f1e..b8d7f32 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/FishingOperationNotValidException.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/FishingOperationNotValidException.java @@ -1,11 +1,9 @@ package fr.ifremer.tutti.service.genericformat.consumer; -import com.google.common.base.Joiner; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; -import org.nuiton.validator.NuitonValidatorResult; -import org.nuiton.validator.NuitonValidatorScope; +import fr.ifremer.tutti.service.genericformat.GenericFormatImportValidationHelper; -import java.util.List; +import java.util.Set; import static org.nuiton.i18n.I18n.t; @@ -21,36 +19,26 @@ public class FishingOperationNotValidException extends Exception { private final FishingOperation fishingOperation; - private final NuitonValidatorResult validatorResult; + private final Set<String> errorMessages; - public FishingOperationNotValidException(FishingOperation fishingOperation, NuitonValidatorResult validatorResult) { + public FishingOperationNotValidException(FishingOperation fishingOperation, Set<String> errorMessages) { this.fishingOperation = fishingOperation; - this.validatorResult = validatorResult; + this.errorMessages = errorMessages; } public FishingOperation getFishingOperation() { return fishingOperation; } + public Set<String> getErrorMessages() { + return errorMessages; + } + @Override public String getMessage() { - StringBuilder builder = new StringBuilder(); - - if (validatorResult.hasFatalMessages()) { - List<String> fatalMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.FATAL); - builder.append("\n").append(t("tutti.fatal.messages", Joiner.on("\n-").join(fatalMessage))); - } - if (validatorResult.hasErrorMessagess()) { - List<String> errorsMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.ERROR); - builder.append("\n").append(t("tutti.error.messages", Joiner.on("\n-").join(errorsMessage))); - } - if (validatorResult.hasWarningMessages()) { - List<String> warningMessage = validatorResult.getMessagesForScope(NuitonValidatorScope.WARNING); - builder.append("\n").append(t("tutti.warning.messages", Joiner.on("\n-").join(warningMessage))); - } - - String message = t("tutti.service.genericFormat.import.error.fishingOperationNotValid", builder.toString()); + String errors = GenericFormatImportValidationHelper.getMessage("", errorMessages); + String message = t("tutti.service.genericFormat.import.error.fishingOperationNotValid", errors); return message; } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/MismatchProgramException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/MismatchProgramException.java new file mode 100644 index 0000000..4ce3475 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/genericformat/consumer/MismatchProgramException.java @@ -0,0 +1,39 @@ +package fr.ifremer.tutti.service.genericformat.consumer; + +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.Program; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 3/2/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.14 + */ +public class MismatchProgramException extends Exception { + + private static final long serialVersionUID = 1L; + + private final Cruise cruise; + + private final Program expectedProgram; + + public MismatchProgramException(Cruise cruise, Program expectedProgram) { + this.cruise = cruise; + this.expectedProgram = expectedProgram; + } + + public Cruise getCruise() { + return cruise; + } + + public Program getExpectedProgram() { + return expectedProgram; + } + + @Override + public String getMessage() { + return t("tutti.service.genericFormat.import.error.mismatchProgram", cruise.getBeginDate(), cruise.getProgram().getName(), cruise.getSurveyPart(), expectedProgram.getName(), expectedProgram.getId()); + } +} diff --git a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties index 4053ecf..dbcd43b 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties @@ -146,7 +146,8 @@ tutti.service.genericFormat.import.cruises=Import des campagnes tutti.service.genericFormat.import.error.cruiseAlreadyExist=Il existe déjà une campagne avec ce nom %s tutti.service.genericFormat.import.error.cruiseAlreadyImported=La campagne avec ce nom %s a déjà été importée tutti.service.genericFormat.import.error.cruiseNotFound=La campagne (année\: %s, série\: %s, série partielle %s) n'existe pas -tutti.service.genericFormat.import.error.cruiseNotValid=La campagne n'est pas valide \: %s +tutti.service.genericFormat.import.error.mismatchProgram=La campagne (année\: %s, série\: %s, série partielle %s) devrait utiliser la série %s (code %s) +tutti.service.genericFormat.import.error.cruiseNotValid=La campagne n'est pas valide \: <ul>%s</ul> tutti.service.genericFormat.import.error.fishingOperationAlreadyImported=Un trait %s - %s - %s -%s a déjà été importé dans la campagne %s tutti.service.genericFormat.import.error.fishingOperationNotFoundInCruise=Le trait %s - %s - %s -%s n'existe pas dans la campagne %s tutti.service.genericFormat.import.error.fishingOperationNotValid=Le trait n'est pas valide \:\n%s diff --git a/tutti-service/src/test/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportServiceValidTest.java b/tutti-service/src/test/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportServiceValidTest.java index 875dbd6..99b1de2 100644 --- a/tutti-service/src/test/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportServiceValidTest.java +++ b/tutti-service/src/test/java/fr/ifremer/tutti/service/genericformat/GenericFormatImportServiceValidTest.java @@ -269,7 +269,8 @@ public class GenericFormatImportServiceValidTest extends GenericFormatImportServ public void testBadSurveyImport() throws IOException { GenericFormatValidateFileResult result = doValidate("testSurveyImportLimitCases", PROGRAM_ID, - "empty", "sampleCategory", "referentials", "protocol", "badSurveyImport"); + "empty", "sampleCategory", "referentials", "protocol", + "badSurveyImport"); Assert.assertTrue(result.isArchiveLayoutValid()); Assert.assertTrue(result.getSampleCategoryFileResult().isImported()); diff --git a/tutti-service/src/test/resources/genericFormat/badSurveyImport/survey.csv b/tutti-service/src/test/resources/genericFormat/badSurveyImport/survey.csv index 987c9f4..b3f1f76 100644 --- a/tutti-service/src/test/resources/genericFormat/badSurveyImport/survey.csv +++ b/tutti-service/src/test/resources/genericFormat/badSurveyImport/survey.csv @@ -1,2 +1,4 @@ Annee;Serie;Serie_Partielle;Navire;Nombre_Poches;Pays;Zone_Etude;Campagne;Id_Sismer;Date_Deb_Campagne;Port_Deb_Campagne;Date_Fin_Campagne;Port_Fin_Campagne;Chef_Mission;Resp_Salle_Tri;Commentaire;Serie_Id;Navire_Id;Engin_Id;Port_Deb_Campagne_Id;Port_Fin_Campagne_Id;Chef_Mission_Id;Resp_Salle_Tri_Id -2014;Campagne EVHOE;1;868095;1;FRA;EVHOE - Golfe de Gascogne / Mer Celtique;Campagne EVHOE 2014;;17/10/2014 07:00:00;Brest;01/12/2014 07:00:00;Brest;Jean-Pierre LEAUTE|Michele SALAUN|Lionel PAWLOWSKI;Erwan DUHAMEL|Nicolas CAROFF;;CAM-EVHOE33;868095;379|381|64;530;530;143|70|2332;128|59 \ No newline at end of file +2014;Campagne EVHOE;1;868095;1;FRA;EVHOE - Golfe de Gascogne / Mer Celtique;Campagne EVHOE 2014;;17/10/2014 07:00:00;Brest;01/12/2014 07:00:00;Brest;Jean-Pierre LEAUTE|Michele SALAUN|Lionel PAWLOWSKI;Erwan DUHAMEL|Nicolas CAROFF;;CAM-IBTS;86809445;37944|38155|64;530;530;1434|703|2332;1282|591 +2014;;1;;1;FRA;EVHOE - Golfe de Gascogne / Mer Celtique;;;;;;;;;;;;;;;; +2014;Campagne EVHOE;1;868095;1;FRA;EVHOE - Golfe de Gascogne / Mer Celtique;Campagne EVHOE 2014;;17/10/2014 07:00:00;Brest;01/10/2014 07:00:00;Brest;Jean-Pierre LEAUTE|Michele SALAUN|Lionel PAWLOWSKI;Erwan DUHAMEL|Nicolas CAROFF;;CAM-EVHOE;868095;379|381|64;530;530;143|70|2332;128|59 -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.