This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 4869f1ae5b17d222175b20c3347e0eb6cf0de7b2 Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed May 11 09:59:38 2016 +0200 o Revue des imports du protocole (pas tout, pas le temps...) o Nettoyage code o Bien importer les maturités + autres caractéristiques lors d'un import de caractéristiques sur le procole (See #8302, #8301) --- .../protocol/ProtocolImportExportService.java | 498 +++++++++++++-------- .../service/pupitri/PupitriImportService.java | 38 +- .../resources/i18n/tutti-service_en_GB.properties | 1 + .../resources/i18n/tutti-service_fr_FR.properties | 1 + 4 files changed, 335 insertions(+), 203 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/ProtocolImportExportService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/ProtocolImportExportService.java index fd0b43e..305d03a 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/ProtocolImportExportService.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/ProtocolImportExportService.java @@ -22,20 +22,18 @@ package fr.ifremer.tutti.service.protocol; * #L% */ -import com.google.common.base.Charsets; -import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import com.google.common.collect.TreeMultimap; import com.google.common.io.Files; import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinitions; import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRow; import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRowBean; import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicType; +import fr.ifremer.tutti.persistence.entities.protocol.MaturityCaracteristic; +import fr.ifremer.tutti.persistence.entities.protocol.MaturityCaracteristics; import fr.ifremer.tutti.persistence.entities.protocol.Rtp; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocols; @@ -45,7 +43,6 @@ import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.service.AbstractTuttiService; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.csv.Export; @@ -60,16 +57,20 @@ import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.nuiton.i18n.I18n.t; @@ -99,66 +100,76 @@ public class ProtocolImportExportService extends AbstractTuttiService { log.info("Will import protocol caracteristic from file: " + file); } - Multimap<CaracteristicType, String> ids = TreeMultimap.create(); - - CaracteristicRowModel csvModel = - new CaracteristicRowModel(getCsvSeparator(), - caracteristicMap); + List<String> lengthClassesPmfmIds = new ArrayList<>(protocol.getLengthClassesPmfmId()); + List<String> individualObservationPmfmId = new ArrayList<>(protocol.getIndividualObservationPmfmId()); + Map<String, MaturityCaracteristic> maturityCaracteristics = new LinkedHashMap<>(); + if (!protocol.isMaturityCaracteristicsEmpty()) { + maturityCaracteristics.putAll(Maps.uniqueIndex(protocol.getMaturityCaracteristics(), MaturityCaracteristic::getId)); + } - Reader reader = Files.newReader(file, Charsets.UTF_8); - try { + Map<String, CaracteristicMappingRow> rowsByCaracteristicId = new LinkedHashMap<>(); + if (!protocol.isCaracteristicMappingEmpty()) { + rowsByCaracteristicId.putAll(Maps.uniqueIndex(protocol.getCaracteristicMapping(), CaracteristicMappingRow::getPmfmId)); + } - Import<CaracteristicRow> importer = - Import.newImport(csvModel, reader); + try (Reader reader = Files.newReader(file, StandardCharsets.UTF_8)) { - try { + CaracteristicRowModel csvModel = new CaracteristicRowModel(getCsvSeparator(), caracteristicMap); + try (Import<CaracteristicRow> importer = Import.newImport(csvModel, reader)) { for (CaracteristicRow bean : importer) { CaracteristicType caracteristicType = bean.getPmfmType(); Caracteristic caracteristic = bean.getPmfm(); String id = caracteristic.getId(); - ids.put(caracteristicType, id); + switch (caracteristicType) { + + case INDIVIDUAL_OBSERVATION: + individualObservationPmfmId.add(id); + break; + case LENGTH_STEP: + lengthClassesPmfmIds.add(id); + break; + case MATURITY: + MaturityCaracteristic maturityCaracteristic = maturityCaracteristics.get(id); + if (maturityCaracteristic==null) { + maturityCaracteristic = MaturityCaracteristics.newMaturityCaracteristic(); + maturityCaracteristic.setId(id); + maturityCaracteristics.put(id, maturityCaracteristic); + } + break; + + case VESSEL_USE_FEATURE: + case GEAR_USE_FEATURE: + CaracteristicMappingRow row = rowsByCaracteristicId.get(id); + if (row == null) { + row = new CaracteristicMappingRowBean(); + row.setPmfmId(id); + row.setTab(caracteristicType.name()); + rowsByCaracteristicId.put(id, row); + } + break; + + } + } - importer.close(); - } finally { - IOUtils.closeQuietly(importer); + } - reader.close(); + } catch (ImportRuntimeException e) { throw e; } catch (Exception e) { throw new ImportRuntimeException("Could not import protocol [" + protocol.getName() + "] caracteristic from file " + file, e); - } finally { - - IOUtils.closeQuietly(reader); - } - - protocol.setLengthClassesPmfmId( - mergeIds(protocol.getLengthClassesPmfmId(), - ids.get(CaracteristicType.LENGTH_STEP)) - ); - - protocol.setIndividualObservationPmfmId( - mergeIds(protocol.getIndividualObservationPmfmId(), - ids.get(CaracteristicType.INDIVIDUAL_OBSERVATION)) - ); - - List<CaracteristicMappingRow> caracteristicMapping = protocol.getCaracteristicMapping(); - if (caracteristicMapping == null) { - caracteristicMapping = new ArrayList<>(); } - Map<String, CaracteristicMappingRow> rowsByCaracteristicId = - new HashMap<>(Maps.uniqueIndex(caracteristicMapping, CaracteristicMappingRow::getPmfmId)); - - mergeCaracteristicMappingRows(ids, rowsByCaracteristicId, CaracteristicType.GEAR_USE_FEATURE); - mergeCaracteristicMappingRows(ids, rowsByCaracteristicId, CaracteristicType.VESSEL_USE_FEATURE); + protocol.setLengthClassesPmfmId(lengthClassesPmfmIds); + protocol.setIndividualObservationPmfmId(individualObservationPmfmId); + protocol.setMaturityCaracteristics(new ArrayList<>(maturityCaracteristics.values())); protocol.setCaracteristicMapping(new ArrayList<>(rowsByCaracteristicId.values())); + } - public void exportAllCaracteristic(File file, - Map<String, Caracteristic> caracteristicMap) { + public void exportAllCaracteristic(File file, Map<String, Caracteristic> caracteristicMap) { if (log.isInfoEnabled()) { log.info("Will export all caracteristics to file: " + file); @@ -167,24 +178,18 @@ public class ProtocolImportExportService extends AbstractTuttiService { PmfmIdToCaracteristicRowFunction function = new PmfmIdToCaracteristicRowFunction(caracteristicMap); - List<CaracteristicRow> rows = Lists.transform( - Lists.newArrayList(caracteristicMap.keySet()), function); + List<CaracteristicRow> rows = caracteristicMap.keySet().stream().map(function).collect(Collectors.toList()); - CaracteristicRowModel csvModel = - new CaracteristicRowModel(getCsvSeparator(), - caracteristicMap); + try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) { - BufferedWriter writer = null; - try { - writer = Files.newWriter(file, Charsets.UTF_8); + CaracteristicRowModel csvModel = new CaracteristicRowModel(getCsvSeparator(), caracteristicMap); Export export = Export.newExport(csvModel, rows); export.write(writer); - writer.close(); + } catch (Exception e) { throw new ImportRuntimeException(t("tutti.service.protocol.export.caracteristics.all.error", file), e); - } finally { - IOUtils.closeQuietly(writer); } + } public void exportProtocolCaracteristic(File file, @@ -195,44 +200,61 @@ public class ProtocolImportExportService extends AbstractTuttiService { log.info("Will export all caracteristics to file: " + file); } - PmfmIdToCaracteristicRowFunction function = - new PmfmIdToCaracteristicRowFunction(caracteristicMap); + List<CaracteristicRow> rows = getProtocolCaracteristicRowsToExport(protocol, caracteristicMap); + + try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) { + + CaracteristicRowModel csvModel = new CaracteristicRowModel(getCsvSeparator(), caracteristicMap); + Export export = Export.newExport(csvModel, rows); + export.write(writer); + + } catch (Exception e) { + throw new ApplicationTechnicalException(t("tutti.service.protocol.export.caracteristics.protocol.error", protocol.getName(), file), e); + } + } - List<CaracteristicRow> rows = Lists.newArrayList(); + private List<CaracteristicRow> getCaracteristicRows(CaracteristicType caracteristicType, Stream<String> ids, PmfmIdToCaracteristicRowFunction function) { + + return ids.map(function) + .map(s -> { + s.setPmfmType(caracteristicType); + return s; + }) + .collect(Collectors.toList()); + } + + private CaracteristicRow getCaracteristicRow(CaracteristicType caracteristicType, String id, PmfmIdToCaracteristicRowFunction function) { + CaracteristicRow row = function.apply(id); + row.setPmfmType(caracteristicType); + return row; + } + + private List<CaracteristicRow> getProtocolCaracteristicRowsToExport(TuttiProtocol protocol, Map<String, Caracteristic> caracteristicMap) { + + List<CaracteristicRow> rows = new ArrayList<>(); + + PmfmIdToCaracteristicRowFunction function = new PmfmIdToCaracteristicRowFunction(caracteristicMap); if (!protocol.isLengthClassesPmfmIdEmpty()) { - function.setType(CaracteristicType.LENGTH_STEP); + rows.addAll(getCaracteristicRows(CaracteristicType.LENGTH_STEP, protocol.getLengthClassesPmfmId().stream(), function)); + } - rows.addAll(Lists.transform(protocol.getLengthClassesPmfmId(), function)); + if (!protocol.isMaturityCaracteristicsEmpty()) { + rows.addAll(getCaracteristicRows(CaracteristicType.MATURITY, protocol.getMaturityCaracteristics().stream().map(MaturityCaracteristic::getId), function)); } if (!protocol.isCaracteristicMappingEmpty()) { for (CaracteristicMappingRow mappingRow : protocol.getCaracteristicMapping()) { - function.setType(CaracteristicType.valueOf(mappingRow.getTab())); - rows.add(function.apply(mappingRow.getPmfmId())); - } - } - if (!protocol.isIndividualObservationPmfmIdEmpty()) { + rows.add(getCaracteristicRow(CaracteristicType.valueOf(mappingRow.getTab()), mappingRow.getPmfmId(), function)); - function.setType(CaracteristicType.INDIVIDUAL_OBSERVATION); - rows.addAll(Lists.transform(protocol.getIndividualObservationPmfmId(), function)); + } } - CaracteristicRowModel csvModel = - new CaracteristicRowModel(getCsvSeparator(), - caracteristicMap); - BufferedWriter writer = null; - try { - writer = Files.newWriter(file, Charsets.UTF_8); - Export export = Export.newExport(csvModel, rows); - export.write(writer); - writer.close(); - } catch (Exception e) { - throw new ApplicationTechnicalException(t("tutti.service.protocol.export.caracteristics.protocol.error", protocol.getName(), file), e); - } finally { - IOUtils.closeQuietly(writer); + if (!protocol.isIndividualObservationPmfmIdEmpty()) { + rows.addAll(getCaracteristicRows(CaracteristicType.INDIVIDUAL_OBSERVATION, protocol.getIndividualObservationPmfmId().stream(), function)); } + return rows; } public List<Species> importProtocolSpecies(File file, @@ -246,7 +268,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { List<Species> result = new ArrayList<>(); - Map<Integer, SpeciesProtocol> ids = Maps.newLinkedHashMap(); + Map<Integer, SpeciesProtocol> ids = new LinkedHashMap<>(); if (!protocol.isSpeciesEmpty()) { @@ -258,7 +280,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { } - Map<Integer, SpeciesProtocol> benthosIds = Maps.newLinkedHashMap(); + Map<Integer, SpeciesProtocol> benthosIds = new LinkedHashMap<>(); if (!protocol.isBenthosEmpty()) { @@ -269,10 +291,9 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - SpeciesRowModel csvModel = SpeciesRowModel.forImport(getCsvSeparator(), caracteristicMap, speciesMap); - - try (Reader reader = Files.newReader(file, Charsets.UTF_8)) { + try (Reader reader = Files.newReader(file, StandardCharsets.UTF_8)) { + SpeciesRowModel csvModel = SpeciesRowModel.forImport(getCsvSeparator(), caracteristicMap, speciesMap); try (Import<SpeciesRow> importer = Import.newImport(csvModel, reader)) { Binder<SpeciesRow, SpeciesProtocol> binder = @@ -296,7 +317,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { sp = SpeciesProtocols.newSpeciesProtocol(); } binder.copy(bean, sp); - sp.setMandatorySampleCategoryId(Lists.newArrayList(bean.getMandatorySampleCategoryId())); + sp.setMandatorySampleCategoryId(new ArrayList<>(bean.getMandatorySampleCategoryId())); cleanRptData(sp); @@ -305,7 +326,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - List<SpeciesProtocol> values = Lists.newArrayList(ids.values()); + List<SpeciesProtocol> values = new ArrayList<>(ids.values()); protocol.setSpecies(values); return result; @@ -319,10 +340,10 @@ public class ProtocolImportExportService extends AbstractTuttiService { } /** - * @param file file to import - * @param protocol existing protocol + * @param file file to import + * @param protocol existing protocol * @param caracteristicMap dictonnary of caracteristics - * @param speciesMap dictionnary of species + * @param speciesMap dictionnary of species * @return The list of the species is not imported because they are already in the species */ public List<Species> importProtocolBenthos(File file, @@ -336,7 +357,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { List<Species> result = new ArrayList<>(); - Map<Integer, SpeciesProtocol> ids = Maps.newLinkedHashMap(); + Map<Integer, SpeciesProtocol> ids = new LinkedHashMap<>(); if (!protocol.isBenthosEmpty()) { @@ -347,7 +368,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - Map<Integer, SpeciesProtocol> speciesIds = Maps.newLinkedHashMap(); + Map<Integer, SpeciesProtocol> speciesIds = new LinkedHashMap<>(); if (!protocol.isSpeciesEmpty()) { @@ -358,10 +379,9 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - SpeciesRowModel csvModel = SpeciesRowModel.forImport(getCsvSeparator(), caracteristicMap, speciesMap); - - try (Reader reader = Files.newReader(file, Charsets.UTF_8)) { + try (Reader reader = Files.newReader(file, StandardCharsets.UTF_8)) { + SpeciesRowModel csvModel = SpeciesRowModel.forImport(getCsvSeparator(), caracteristicMap, speciesMap); try (Import<SpeciesRow> importer = Import.newImport(csvModel, reader)) { Binder<SpeciesRow, SpeciesProtocol> binder = @@ -392,7 +412,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - List<SpeciesProtocol> values = Lists.newArrayList(ids.values()); + List<SpeciesProtocol> values = new ArrayList<>(ids.values()); protocol.setBenthos(values); } @@ -412,7 +432,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { List<String> result = new ArrayList<>(headers.length); for (String header : headers) { if ((header.startsWith("\"") && header.endsWith("\"")) || - (header.startsWith("'") && header.endsWith("'"))) { + (header.startsWith("'") && header.endsWith("'"))) { header = header.substring(1, header.length() - 1); } result.add(header); @@ -430,16 +450,24 @@ public class ProtocolImportExportService extends AbstractTuttiService { log.info("Will export species to file: " + file); } - List<SpeciesRow> rows = Lists.newArrayList(); + List<SpeciesRow> rows; + + if (CollectionUtils.isEmpty(protocol)) { + + rows = null; + + } else { + + rows = protocol.stream().map(new SpeciesProtocolToSpeciesRowFunction(caracteristicMap, speciesMap)).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(protocol)) { - rows = Lists.transform(protocol, new SpeciesProtocolToSpeciesRowFunction(caracteristicMap, speciesMap)); } - SpeciesRowModel csvModel = SpeciesRowModel.forExport(getCsvSeparator()); - try (BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8)) { + try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) { + + SpeciesRowModel csvModel = SpeciesRowModel.forExport(getCsvSeparator()); Export export = Export.newExport(csvModel, rows); export.write(writer); + } catch (Exception e) { throw new ApplicationTechnicalException(t("tutti.service.protocol.export.species.error", file), e); } @@ -453,27 +481,35 @@ public class ProtocolImportExportService extends AbstractTuttiService { log.info("Will export benthos to file: " + file); } - List<SpeciesRow> rows = Lists.newArrayList(); + List<SpeciesRow> rows; + + if (CollectionUtils.isEmpty(protocol)) { + + rows = null; + + } else { + + rows = protocol.stream().map(new SpeciesProtocolToSpeciesRowFunction(caracteristicMap, speciesMap)).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(protocol)) { - rows = Lists.transform(protocol, new SpeciesProtocolToSpeciesRowFunction(caracteristicMap, speciesMap)); } - SpeciesRowModel csvModel = SpeciesRowModel.forExport(getCsvSeparator()); - try (BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8)) { + try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) { + + SpeciesRowModel csvModel = SpeciesRowModel.forExport(getCsvSeparator()); Export export = Export.newExport(csvModel, rows); export.write(writer); + } catch (Exception e) { throw new ApplicationTechnicalException(t("tutti.service.protocol.export.benthos.error", file), e); } } /** - * @param file file to import - * @param protocol existing protocol + * @param file file to import + * @param protocol existing protocol * @param allSpecies dictionnary of species * @return The list of the species is not imported because they are already in the species - * or not in the protocol species + * or not in the protocol species */ public Set<Species> importCalcifiedPiecesSamplings(File file, TuttiProtocol protocol, @@ -485,71 +521,129 @@ public class ProtocolImportExportService extends AbstractTuttiService { Set<Species> result = new HashSet<>(); - CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forImport(getCsvSeparator(), allSpecies); - - try (Reader reader = Files.newReader(file, Charsets.UTF_8)) { + try (Reader reader = Files.newReader(file, StandardCharsets.UTF_8)) { + CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forImport(getCsvSeparator(), allSpecies); try (Import<CalcifiedPiecesSamplingRow> importer = Import.newImport(csvModel, reader)) { - Collection<SpeciesProtocol> availableSpeciesProtocol = new ArrayList<>(); - if (!protocol.isSpeciesEmpty()) { - availableSpeciesProtocol.addAll(protocol.getSpecies()); - } - if (!protocol.isBenthosEmpty()) { - availableSpeciesProtocol.addAll(protocol.getBenthos()); - } - - Map<Integer, SpeciesProtocol>availableSpeciesProtocolMap = - availableSpeciesProtocol.stream() - .filter(SpeciesProtocol::isCalcifiedPiecesSamplingDefinitionEmpty) - .collect(Collectors.toMap(SpeciesProtocol::getSpeciesReferenceTaxonId, - java.util.function.Function.identity())); + Binder<CalcifiedPiecesSamplingRow, CalcifiedPiecesSamplingDefinition> binder = + BinderFactory.newBinder(CalcifiedPiecesSamplingRow.class, CalcifiedPiecesSamplingDefinition.class); + Map<Integer, SpeciesProtocol> availableSpeciesProtocolMap = availableSpeciesProtocolMap(protocol); - Multimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> cpsDefBTSpecies = ArrayListMultimap.create(); + // contient les définitions sans maturité définie groupées par leur espèce du protocole + ArrayListMultimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitionsWithoutMaturity = ArrayListMultimap.create(); + // contient les définitions avec une maturité définie à vrai groupées par leur espèce du protocole + ArrayListMultimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitionsWithTrueMaturity = ArrayListMultimap.create(); + // contient les définitions avec une maturité définie à faux groupées par leur espèce du protocole + ArrayListMultimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitionsWithFalseMaturity = ArrayListMultimap.create(); - Binder<CalcifiedPiecesSamplingRow, CalcifiedPiecesSamplingDefinition> binder = - BinderFactory.newBinder(CalcifiedPiecesSamplingRow.class, CalcifiedPiecesSamplingDefinition.class); + // les espèces du protocole liés à des définitions avec ET sans maturité (ce qui est interdit) + Set<SpeciesProtocol> speciesProtocolsWithAndWithoutMaturity = new LinkedHashSet<>(); for (CalcifiedPiecesSamplingRow bean : importer) { Species species = bean.getSpecies(); - Integer id = species.getReferenceTaxonId(); - SpeciesProtocol sp = availableSpeciesProtocolMap.get(id); + if (result.contains(species)) { + + // already done + continue; + } + + SpeciesProtocol speciesProtocol = availableSpeciesProtocolMap.get(species.getReferenceTaxonId()); + + if (speciesProtocol == null) { - if (sp == null || sp.getLengthStepPmfmId() == null) { + if (log.isDebugEnabled()) { + log.debug("Skip species: " + species + ", not found in protocol."); + } result.add(species); + continue; - } else { + } - CalcifiedPiecesSamplingDefinition cpsDef = - CalcifiedPiecesSamplingDefinitions.newCalcifiedPiecesSamplingDefinition(); + if (speciesProtocol.getLengthStepPmfmId() == null) { - binder.copy(bean, cpsDef); + if (log.isDebugEnabled()) { + log.debug("Skip species: " + species + ", found in protocol, but with no length class."); + } + result.add(species); + continue; - cpsDefBTSpecies.put(sp, cpsDef); } - } - cpsDefBTSpecies.keySet().forEach(speciesProtocol -> { + Multimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitions; + + CalcifiedPiecesSamplingDefinition definition = CalcifiedPiecesSamplingDefinitions.newCalcifiedPiecesSamplingDefinition(bean, binder); + + Boolean maturity = definition.getMaturity(); - Integer refTaxId = speciesProtocol.getSpeciesReferenceTaxonId(); - List<CalcifiedPiecesSamplingDefinition> cpsDefs = new ArrayList<>(cpsDefBTSpecies.get(speciesProtocol)); + if (maturity == null) { - if (cpsDefs.stream().allMatch(cpsDef -> cpsDef.getMaturity() == null)) { - checkCpfDefsValidity(refTaxId, cpsDefs); + if (log.isDebugEnabled()) { + log.debug("On species: " + species + ", add definition with no maturity defined (" + definition + ")"); + } + + calcifiedPiecesSamplingDefinitions = calcifiedPiecesSamplingDefinitionsWithoutMaturity; - } else if (!cpsDefs.stream().allMatch(cpsDef -> cpsDef.getMaturity() != null)) { - throw new ImportRuntimeException(t("tutti.service.protocol.import.cps.maturity.error", refTaxId)); + if (calcifiedPiecesSamplingDefinitionsWithTrueMaturity.containsKey(speciesProtocol) || + calcifiedPiecesSamplingDefinitionsWithFalseMaturity.containsKey(speciesProtocol)) { + + // espèce déjà référencé comme avec maturité renseigné, on marque l'espèce + speciesProtocolsWithAndWithoutMaturity.add(speciesProtocol); + } } else { - checkCpfDefsValidity(refTaxId, cpsDefs.stream().filter(CalcifiedPiecesSamplingDefinition::getMaturity).collect(Collectors.toList())); - checkCpfDefsValidity(refTaxId, cpsDefs.stream().filter(cpsDef -> !cpsDef.getMaturity()).collect(Collectors.toList())); + + if (calcifiedPiecesSamplingDefinitionsWithoutMaturity.containsKey(speciesProtocol)) { + + // espèce déjà référencé comme sans maturité renseignée, on marque l'espèce + speciesProtocolsWithAndWithoutMaturity.add(speciesProtocol); + } + + if (maturity) { + + if (log.isDebugEnabled()) { + log.debug("On species: " + species + ", add definition with maturity defined to True (" + definition + ")"); + } + + calcifiedPiecesSamplingDefinitions = calcifiedPiecesSamplingDefinitionsWithTrueMaturity; + } else { + + if (log.isDebugEnabled()) { + log.debug("On species: " + species + ", add definition with maturity defined to False (" + definition + ")"); + } + calcifiedPiecesSamplingDefinitions = calcifiedPiecesSamplingDefinitionsWithFalseMaturity; + } } - speciesProtocol.setCalcifiedPiecesSamplingDefinition(cpsDefs); - }); + calcifiedPiecesSamplingDefinitions.put(speciesProtocol, definition); + + } + + if (!speciesProtocolsWithAndWithoutMaturity.isEmpty()) { + + // on a trouvé des espèces invalide vis-vis de la maturité + // i.e des espèces ayant des définitions avec et sans maturité + String badSpecies = speciesProtocolsWithAndWithoutMaturity.stream() + .map(speciesProtocol -> { + String speciesToString = speciesProtocol.getSpeciesReferenceTaxonId() + ""; + if (speciesProtocol.getSpeciesSurveyCode() != null) { + speciesToString += " (" + speciesProtocol.getSpeciesSurveyCode() + " )"; + } + return speciesToString; + }) + .collect(Collectors.joining("", "<li>", "</li>")); + throw new ImportRuntimeException(t("tutti.service.protocol.import.cps.speciesWithMaturityAndWithoutMaturity.error", badSpecies)); + + } + + Comparator<CalcifiedPiecesSamplingDefinition> definitionsComparator = Comparator.comparing(CalcifiedPiecesSamplingDefinition::getMinSize); + + checkCpfDefinitionsValidity(definitionsComparator, calcifiedPiecesSamplingDefinitionsWithoutMaturity); + checkCpfDefinitionsValidity(definitionsComparator, calcifiedPiecesSamplingDefinitionsWithTrueMaturity); + checkCpfDefinitionsValidity(definitionsComparator, calcifiedPiecesSamplingDefinitionsWithFalseMaturity); } @@ -570,7 +664,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { log.info("Will export cps to file: " + file); } - List<CalcifiedPiecesSamplingRow> rows = Lists.newArrayList(); + List<CalcifiedPiecesSamplingRow> rows = new ArrayList<>(); Binder<CalcifiedPiecesSamplingDefinition, CalcifiedPiecesSamplingRow> binder = BinderFactory.newBinder(CalcifiedPiecesSamplingDefinition.class, CalcifiedPiecesSamplingRow.class); @@ -591,9 +685,9 @@ public class ProtocolImportExportService extends AbstractTuttiService { }); }); + try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) { - CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forExport(getCsvSeparator()); - try (BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8)) { + CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forExport(getCsvSeparator()); Export export = Export.newExport(csvModel, rows); export.write(writer); @@ -606,30 +700,19 @@ public class ProtocolImportExportService extends AbstractTuttiService { return context.getConfig().getCsvSeparator(); } - protected List<String> mergeIds(Collection<String> fromProtocol, Collection<String> fromImport) { - List<String> result = Lists.newArrayList(); - - if (CollectionUtils.isNotEmpty(fromProtocol)) { - fromProtocol.stream().filter(s -> !result.contains(s)).forEach(result::add); - } - fromImport.stream().filter(s -> !result.contains(s)).forEach(result::add); - return result; - } - - - protected void mergeCaracteristicMappingRows(Multimap<CaracteristicType, String> ids, - Map<String, CaracteristicMappingRow> rowsByCaracteristicId, - CaracteristicType type) { - for (String id : ids.get(type)) { - CaracteristicMappingRow row = rowsByCaracteristicId.get(id); - if (row == null) { - row = new CaracteristicMappingRowBean(); - row.setPmfmId(id); - rowsByCaracteristicId.put(id, row); - } - row.setTab(type.name()); - } - } +// protected void mergeCaracteristicMappingRows(Multimap<CaracteristicType, String> ids, +// Map<String, CaracteristicMappingRow> rowsByCaracteristicId, +// CaracteristicType type) { +// for (String id : ids.get(type)) { +// CaracteristicMappingRow row = rowsByCaracteristicId.get(id); +// if (row == null) { +// row = new CaracteristicMappingRowBean(); +// row.setPmfmId(id); +// rowsByCaracteristicId.put(id, row); +// } +// row.setTab(type.name()); +// } +// } protected void cleanRptData(SpeciesProtocol sp) { if (sp.withRtpMale()) { @@ -652,26 +735,51 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } - protected void checkCpfDefsValidity(Integer referenceTaxonId, List<CalcifiedPiecesSamplingDefinition> cpsDefs) { - cpsDefs.sort(Comparator.comparing(CalcifiedPiecesSamplingDefinition::getMinSize)); - - Integer min = -1; - for (CalcifiedPiecesSamplingDefinition cpfDef : cpsDefs) { - if (cpfDef.getMinSize() != min + 1) { - throw new ImportRuntimeException(t("tutti.service.protocol.import.cps.interval.error", - referenceTaxonId, - cpfDef.getMaturity(), - min, - cpfDef.getMinSize())); + protected void checkCpfDefinitionsValidity(Comparator<CalcifiedPiecesSamplingDefinition> definitionsComparator, ArrayListMultimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitions) { + + calcifiedPiecesSamplingDefinitions.asMap().forEach((speciesProtocol, unsortedDefinitions) -> { + + List<CalcifiedPiecesSamplingDefinition> sortedDefinitions = new ArrayList<>(unsortedDefinitions); + sortedDefinitions.sort(definitionsComparator); + + Integer min = -1; + for (CalcifiedPiecesSamplingDefinition definition : sortedDefinitions) { + if (definition.getMinSize() != min + 1) { + + throw new ImportRuntimeException(t("tutti.service.protocol.import.cps.interval.error", + speciesProtocol.getSpeciesReferenceTaxonId(), + definition.getMaturity(), + min, + definition.getMinSize())); + } + min = definition.getMaxSize(); } - min = cpfDef.getMaxSize(); + + speciesProtocol.setCalcifiedPiecesSamplingDefinition(sortedDefinitions); + + }); + + } + + private Map<Integer, SpeciesProtocol> availableSpeciesProtocolMap(TuttiProtocol protocol) { + + Collection<SpeciesProtocol> availableSpeciesProtocol = new ArrayList<>(); + if (!protocol.isSpeciesEmpty()) { + availableSpeciesProtocol.addAll(protocol.getSpecies()); + } + if (!protocol.isBenthosEmpty()) { + availableSpeciesProtocol.addAll(protocol.getBenthos()); } + + return availableSpeciesProtocol.stream() + .filter(SpeciesProtocol::isCalcifiedPiecesSamplingDefinitionEmpty) + .collect(Collectors.toMap(SpeciesProtocol::getSpeciesReferenceTaxonId, Function.identity())); + + } private static class PmfmIdToCaracteristicRowFunction implements Function<String, CaracteristicRow> { - private CaracteristicType type; - private final Map<String, Caracteristic> caracteristicMap; public PmfmIdToCaracteristicRowFunction(Map<String, Caracteristic> caracteristicMap) { @@ -684,13 +792,9 @@ public class ProtocolImportExportService extends AbstractTuttiService { Preconditions.checkNotNull(caracteristic, "Could not find a caracteristic with id: " + input); CaracteristicRow result = new CaracteristicRow(); result.setPmfm(caracteristic); - result.setPmfmType(type); return result; } - public void setType(CaracteristicType type) { - this.type = type; - } } private static class SpeciesProtocolToSpeciesRowFunction implements Function<SpeciesProtocol, SpeciesRow> { @@ -721,7 +825,7 @@ public class ProtocolImportExportService extends AbstractTuttiService { } result.setSpecies(species); // always use a copy of list - result.setMandatorySampleCategoryId(Lists.newArrayList(input.getMandatorySampleCategoryId())); + result.setMandatorySampleCategoryId(new ArrayList<>(input.getMandatorySampleCategoryId())); return result; } } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/pupitri/PupitriImportService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/pupitri/PupitriImportService.java index 28b0e9f..d388980 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/pupitri/PupitriImportService.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/pupitri/PupitriImportService.java @@ -36,8 +36,9 @@ import fr.ifremer.tutti.persistence.entities.data.CatchBatch; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchs; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocols; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; -import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocols; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValues; @@ -59,7 +60,6 @@ import fr.ifremer.tutti.service.pupitri.csv.TrunkRowModel; import fr.ifremer.tutti.service.pupitri.report.PupitriImportReportModel; import fr.ifremer.tutti.service.pupitri.report.PupitriImportReportRow; import fr.ifremer.tutti.type.WeightUnit; -import fr.ifremer.tutti.util.Weights; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; @@ -78,9 +78,13 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Collectors; import static org.nuiton.i18n.I18n.n; import static org.nuiton.i18n.I18n.t; @@ -514,13 +518,13 @@ public class PupitriImportService extends AbstractTuttiService { // especes à sexer Collection<String> surveyCodesToSex = - TuttiProtocols.getSurveyCodeWhoseCategoryIsMandatory(protocol, - persistenceService.getSexCaracteristic()); + getSurveyCodeWhoseCategoryIsMandatory(protocol, + persistenceService.getSexCaracteristic()); // especes à trier par taille Collection<String> surveyCodesToSize = - TuttiProtocols.getSurveyCodeWhoseCategoryIsMandatory(protocol, - persistenceService.getSizeCategoryCaracteristic()); + getSurveyCodeWhoseCategoryIsMandatory(protocol, + persistenceService.getSizeCategoryCaracteristic()); // especes à sexer et trier par taille Collection<String> surveyCodesToSexAndSize = CollectionUtils.intersection(surveyCodesToSex, surveyCodesToSize); @@ -674,4 +678,26 @@ public class PupitriImportService extends AbstractTuttiService { return fileWithHeaders; } + + private Collection<String> getSurveyCodeWhoseCategoryIsMandatory(TuttiProtocol protocol, Caracteristic caracteristic) { + + Objects.requireNonNull(caracteristic); + + Collection<String> surveyCodes; + + if (protocol == null) { + + surveyCodes = new HashSet<>(); + + } else { + + Predicate<SpeciesProtocol> predicate = SpeciesProtocols.speciesProtocolWhoseCategoryIsMandatoryPredicate(caracteristic); + Collection<SpeciesProtocol> speciesProtocols = protocol.getSpecies().stream().filter(predicate).collect(Collectors.toSet()); + + surveyCodes = speciesProtocols.stream().map(SpeciesProtocol::getSpeciesSurveyCode).collect(Collectors.toSet()); + + } + + return surveyCodes; + } } diff --git a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties index 810d8ea..d7f82a5 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties @@ -261,6 +261,7 @@ tutti.service.protocol.import.benthos.error= tutti.service.protocol.import.cps.error= tutti.service.protocol.import.cps.interval.error= tutti.service.protocol.import.cps.maturity.error= +tutti.service.protocol.import.cps.speciesWithMaturityAndWithoutMaturity.error= tutti.service.protocol.import.species.error= tutti.service.protocol.import.taxonUsed.error= tutti.service.psion.import.attachment.comment= 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 9b0cc67..5240ede 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 @@ -310,6 +310,7 @@ tutti.service.protocol.import.benthos.error=Erreur lors de l'import du benthos d tutti.service.protocol.import.cps.error=Erreur lors de l'import de l'algorithme de prélèvements des pièces calcifiées dans le protocole %s depuis le fichier %s tutti.service.protocol.import.cps.interval.error=Erreur sur la ligne espèces %s (%s) taille minimale attendue \: %s, réelle \: %s tutti.service.protocol.import.cps.maturity.error=Erreur sur la maturité pour l'espèces %s +tutti.service.protocol.import.cps.speciesWithMaturityAndWithoutMaturity.error=<html><body>Les espèces suivantes sont utilisées dans des définitions avec et sans maturité ce qui n'est pas autorisé \: <ul>%s</ul></body></html> tutti.service.protocol.import.species.error=Erreur lors de l'import des espèces du protocole %1s du fichier %2s tutti.service.protocol.import.taxonUsed.error=Le taxon référent d'id %s est déjà utilisé tutti.service.psion.import.attachment.comment=Import Psion du %s -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.