This is an automated email from the git hooks/post-receive script. New commit to branch feature/7930 in repository tutti. See http://git.codelutin.com/tutti.git commit 51a31e3db513a8e51d977876eabd8354b5ea6632 Author: Kevin Morin <morin@codelutin.com> Date: Tue Feb 16 16:26:11 2016 +0100 ajout de l'import export (refs #7930) --- .../csv/AbstractTuttiImportExportModel.java | 4 + .../protocol/CalcifiedPiecesSamplingRow.java | 112 +++++++++++++ .../protocol/CalcifiedPiecesSamplingRowModel.java | 70 ++++++++ .../protocol/ProtocolImportExportService.java | 157 ++++++++++++++++++ .../tutti/service/protocol/SpeciesRowModel.java | 12 +- .../resources/i18n/tutti-service_en_GB.properties | 5 + .../resources/i18n/tutti-service_fr_FR.properties | 4 + .../content/protocol/EditProtocolUIModel.java | 57 +++++++ .../actions/ImportProtocolBenthosAction.java | 36 +++-- .../actions/ImportProtocolSpeciesAction.java | 36 +++-- .../actions/RemoveBenthosProtocolAction.java | 6 +- .../actions/RemoveSpeciesProtocolAction.java | 6 +- .../protocol/actions/SaveProtocolAction.java | 54 ------- .../CalcifiedPiecesSamplingEditorUI.jaxx | 5 + .../CalcifiedPiecesSamplingEditorUI.jcss | 18 +++ .../CalcifiedPiecesSamplingEditorUIHandler.java | 7 +- .../actions/ExportProtocolCpsAction.java | 116 +++++++++++++ .../actions/ImportProtocolCpsAction.java | 179 +++++++++++++++++++++ .../resources/i18n/tutti-ui-swing_en_GB.properties | 14 ++ .../resources/i18n/tutti-ui-swing_fr_FR.properties | 14 ++ 20 files changed, 818 insertions(+), 94 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/csv/AbstractTuttiImportExportModel.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/csv/AbstractTuttiImportExportModel.java index 2ae256e..3995c3f 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/csv/AbstractTuttiImportExportModel.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/csv/AbstractTuttiImportExportModel.java @@ -48,6 +48,10 @@ public abstract class AbstractTuttiImportExportModel<M> extends AbstractImportEx super(separator); } + public <E extends TuttiEntity> void newForeignKeyColumn(String propertyName, Class<E> entityType, String foreignKeyName, Map<String, E> universe) { + newMandatoryColumn(propertyName, propertyName, new ForeignKeyParserFormatter<>(entityType, foreignKeyName, universe)); + } + public <E extends TuttiEntity> void newForeignKeyColumn(String headerName, String propertyName, Class<E> entityType, String foreignKeyName, Map<String, E> universe) { newMandatoryColumn(headerName, propertyName, new ForeignKeyParserFormatter<>(entityType, foreignKeyName, universe)); } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRow.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRow.java new file mode 100644 index 0000000..dacf1fc --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRow.java @@ -0,0 +1,112 @@ +package fr.ifremer.tutti.service.protocol; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinitions; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.io.Serializable; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class CalcifiedPiecesSamplingRow implements Serializable { + + public static final String PROPERTY_SPECIES = "species"; + + public static final String PROPERTY_MIN_SIZE = "minSize"; + + public static final String PROPERTY_MAX_SIZE = "maxSize"; + + public static final String PROPERTY_MATURITY = "maturity"; + + public static final String PROPERTY_SEX = "sex"; + + public static final String PROPERTY_MAX_BY_LENGHT_STEP = "maxByLenghtStep"; + + public static final String PROPERTY_SAMPLING_INTERVAL = "samplingInterval"; + + public static final String PROPERTY_OPERATION_LIMITATION = "operationLimitation"; + + public static final String PROPERTY_ZONE_LIMITATION = "zoneLimitation"; + + protected Species species; + + protected CalcifiedPiecesSamplingDefinition delegate; + + public CalcifiedPiecesSamplingRow() { + delegate = CalcifiedPiecesSamplingDefinitions.newCalcifiedPiecesSamplingDefinition(); + } + + public Species getSpecies() { + return species; + } + + public void setSpecies(Species species) { + this.species = species; + } + + public Boolean getMaturity() { + return delegate.getMaturity(); + } + + public Integer getMaxByLenghtStep() { + return delegate.getMaxByLenghtStep(); + } + + public Integer getMaxSize() { + return delegate.getMaxSize(); + } + + public int getMinSize() { + return delegate.getMinSize(); + } + + public int getSamplingInterval() { + return delegate.getSamplingInterval(); + } + + public Integer getOperationLimitation() { + return delegate.getOperationLimitation(); + } + + public Integer getZoneLimitation() { + return delegate.getZoneLimitation(); + } + + public boolean isSex() { + return delegate.isSex(); + } + + public void setMaturity(Boolean maturity) { + delegate.setMaturity(maturity); + } + + public void setMaxByLenghtStep(Integer maxByLenghtStep) { + delegate.setMaxByLenghtStep(maxByLenghtStep); + } + + public void setMaxSize(Integer maxSize) { + delegate.setMaxSize(maxSize); + } + + public void setMinSize(int minSize) { + delegate.setMinSize(minSize); + } + + public void setOperationLimitation(Integer operationLimitation) { + delegate.setOperationLimitation(operationLimitation); + } + + public void setSamplingInterval(int samplingInterval) { + delegate.setSamplingInterval(samplingInterval); + } + + public void setSex(boolean sex) { + delegate.setSex(sex); + } + + public void setZoneLimitation(Integer zoneLimitation) { + delegate.setZoneLimitation(zoneLimitation); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRowModel.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRowModel.java new file mode 100644 index 0000000..f489ead --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/CalcifiedPiecesSamplingRowModel.java @@ -0,0 +1,70 @@ +package fr.ifremer.tutti.service.protocol; + +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.csv.AbstractTuttiImportExportModel; +import fr.ifremer.tutti.service.csv.TuttiCsvUtil; +import org.nuiton.csv.ValueFormatter; + +import java.util.Map; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class CalcifiedPiecesSamplingRowModel extends AbstractTuttiImportExportModel<CalcifiedPiecesSamplingRow> { + + public CalcifiedPiecesSamplingRowModel(char separator) { + super(separator); + } + + public static CalcifiedPiecesSamplingRowModel forExport(char separator) { + + CalcifiedPiecesSamplingRowModel result = new CalcifiedPiecesSamplingRowModel(separator); + + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_SPECIES, + new ValueFormatter<Species>() { + + @Override + public String format(Species species) { + return String.valueOf(species.getReferenceTaxonId()); + } + }); + + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_MATURITY, TuttiCsvUtil.BOOLEAN); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_SEX, TuttiCsvUtil.PRIMITIVE_BOOLEAN); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_MIN_SIZE, TuttiCsvUtil.PRIMITIVE_INTEGER); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_MAX_SIZE, TuttiCsvUtil.INTEGER); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_MAX_BY_LENGHT_STEP, TuttiCsvUtil.INTEGER); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_SAMPLING_INTERVAL, TuttiCsvUtil.PRIMITIVE_INTEGER); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_OPERATION_LIMITATION, TuttiCsvUtil.INTEGER); + result.newColumnForExport(CalcifiedPiecesSamplingRow.PROPERTY_ZONE_LIMITATION, TuttiCsvUtil.INTEGER); + + return result; + } + + public static CalcifiedPiecesSamplingRowModel forImport(char separator, + Map<String, Species> allSpecies) { + + CalcifiedPiecesSamplingRowModel result = new CalcifiedPiecesSamplingRowModel(separator); + + result.newForeignKeyColumn(CalcifiedPiecesSamplingRow.PROPERTY_SPECIES, + Species.class, + Species.PROPERTY_REFERENCE_TAXON_ID, + allSpecies); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_MATURITY, TuttiCsvUtil.BOOLEAN); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_SEX, TuttiCsvUtil.PRIMITIVE_BOOLEAN); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_MIN_SIZE, TuttiCsvUtil.PRIMITIVE_INTEGER); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_MAX_SIZE, TuttiCsvUtil.INTEGER); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_MAX_BY_LENGHT_STEP, TuttiCsvUtil.INTEGER); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_SAMPLING_INTERVAL, TuttiCsvUtil.PRIMITIVE_INTEGER); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_OPERATION_LIMITATION, TuttiCsvUtil.INTEGER); + result.newMandatoryColumn(CalcifiedPiecesSamplingRow.PROPERTY_ZONE_LIMITATION, TuttiCsvUtil.INTEGER); + + return result; + } + + @Override + public CalcifiedPiecesSamplingRow newEmptyInstance() { + return new CalcifiedPiecesSamplingRow(); + } +} 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 11da1e6..3dff330 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 @@ -25,11 +25,14 @@ package fr.ifremer.tutti.service.protocol; 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; @@ -60,9 +63,13 @@ import java.io.Reader; 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.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import static org.nuiton.i18n.I18n.t; @@ -468,6 +475,140 @@ public class ProtocolImportExportService extends AbstractTuttiService { } } + /** + * @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 + */ + public Set<Species> importCalcifiedPiecesSamplings(File file, + TuttiProtocol protocol, + Map<String, Species> allSpecies) { + + if (log.isInfoEnabled()) { + log.info("Will import protocol [" + protocol.getName() + "] cps from file: " + file); + } + + Set<Species> result = new HashSet<>(); + + CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forImport(getCsvSeparator(), allSpecies); + + try (Reader reader = Files.newReader(file, Charsets.UTF_8)) { + + 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())); + + + Multimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> cpsDefBTSpecies = ArrayListMultimap.create(); + + Binder<CalcifiedPiecesSamplingRow, CalcifiedPiecesSamplingDefinition> binder = + BinderFactory.newBinder(CalcifiedPiecesSamplingRow.class, CalcifiedPiecesSamplingDefinition.class); + + for (CalcifiedPiecesSamplingRow bean : importer) { + + Species species = bean.getSpecies(); + Integer id = species.getReferenceTaxonId(); + + SpeciesProtocol sp = availableSpeciesProtocolMap.get(id); + + if (sp == null) { + result.add(species); + + } else { + + CalcifiedPiecesSamplingDefinition cpsDef = + CalcifiedPiecesSamplingDefinitions.newCalcifiedPiecesSamplingDefinition(); + + binder.copy(bean, cpsDef); + + cpsDefBTSpecies.put(sp, cpsDef); + } + } + + cpsDefBTSpecies.keySet().forEach(speciesProtocol -> { + + Integer refTaxId = speciesProtocol.getSpeciesReferenceTaxonId(); + List<CalcifiedPiecesSamplingDefinition> cpsDefs = new ArrayList<>(cpsDefBTSpecies.get(speciesProtocol)); + + if (cpsDefs.stream().allMatch(cpsDef -> cpsDef.getMaturity() == null)) { + checkCpfDefsValidity(refTaxId, cpsDefs); + + } else if (!cpsDefs.stream().allMatch(cpsDef -> cpsDef.getMaturity() != null)) { + throw new ImportRuntimeException(t("tutti.service.protocol.import.cps.maturity.error", refTaxId)); + + } else { + checkCpfDefsValidity(refTaxId, cpsDefs.stream().filter(cpsDef -> cpsDef.getMaturity()).collect(Collectors.toList())); + checkCpfDefsValidity(refTaxId, cpsDefs.stream().filter(cpsDef -> !cpsDef.getMaturity()).collect(Collectors.toList())); + } + + speciesProtocol.setCalcifiedPiecesSamplingDefinition(cpsDefs); + }); + + } + + } catch (ImportRuntimeException e) { + throw e; + } catch (Exception e) { + throw new ApplicationTechnicalException(t("tutti.service.protocol.import.cps.error", protocol.getName(), file), e); + } + + return result; + } + + public void exportCalcifiedPiecesSamplings(File file, + Multimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> cps, + Map<String, Species> speciesByReferenceTaxonId) { + + if (log.isInfoEnabled()) { + log.info("Will export cps to file: " + file); + } + + List<CalcifiedPiecesSamplingRow> rows = Lists.newArrayList(); + + Binder<CalcifiedPiecesSamplingDefinition, CalcifiedPiecesSamplingRow> binder = + BinderFactory.newBinder(CalcifiedPiecesSamplingDefinition.class, CalcifiedPiecesSamplingRow.class); + + cps.keySet().forEach(speciesProtocol -> { + + Collection<CalcifiedPiecesSamplingDefinition> calcifiedPiecesSamplingDefinitions = cps.get(speciesProtocol); + + calcifiedPiecesSamplingDefinitions.forEach(cpsDef -> { + + CalcifiedPiecesSamplingRow row = new CalcifiedPiecesSamplingRow(); + binder.copy(cpsDef, row); + String refTaxId = String.valueOf(speciesProtocol.getSpeciesReferenceTaxonId()); + Species species = speciesByReferenceTaxonId.get(refTaxId); + row.setSpecies(species); + rows.add(row); + + }); + }); + + + CalcifiedPiecesSamplingRowModel csvModel = CalcifiedPiecesSamplingRowModel.forExport(getCsvSeparator()); + try (BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8)) { + Export export = Export.newExport(csvModel, rows); + export.write(writer); + + } catch (Exception e) { + throw new ApplicationTechnicalException(t("tutti.service.protocol.export.cps.error", file), e); + } + } + protected char getCsvSeparator() { return context.getConfig().getCsvSeparator(); } @@ -526,6 +667,22 @@ 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())); + } + min = cpfDef.getMaxSize(); + } + } + private static class PmfmIdToCaracteristicRowFunction implements Function<String, CaracteristicRow> { private CaracteristicType type; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/SpeciesRowModel.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/SpeciesRowModel.java index b274703..42b7937 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/SpeciesRowModel.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/protocol/SpeciesRowModel.java @@ -63,11 +63,11 @@ public class SpeciesRowModel extends AbstractTuttiImportExportModel<SpeciesRow> result.newColumnForExport(SpeciesRow.PROPERTY_WEIGHT_ENABLED, Common.PRIMITIVE_BOOLEAN); result.newColumnForExport(SpeciesRow.PROPERTY_COUNT_IF_NO_FREQUENCY_ENABLED, Common.PRIMITIVE_BOOLEAN); result.newColumnForExport(SpeciesRow.PROPERTY_CALCIFY_SAMPLE_ENABLED, Common.PRIMITIVE_BOOLEAN); - result.newColumnForExport(SpeciesRow.PROPERTY_RTP_MALE_A, Common.FLOAT); + result.newColumnForExport(SpeciesRow.PROPERTY_RTP_MALE_A, Common.DOUBLE); result.newColumnForExport(SpeciesRow.PROPERTY_RTP_MALE_B, Common.FLOAT); - result.newColumnForExport(SpeciesRow.PROPERTY_RTP_FEMALE_A, Common.FLOAT); + result.newColumnForExport(SpeciesRow.PROPERTY_RTP_FEMALE_A, Common.DOUBLE); result.newColumnForExport(SpeciesRow.PROPERTY_RTP_FEMALE_B, Common.FLOAT); - result.newColumnForExport(SpeciesRow.PROPERTY_RTP_UNDEFINED_A, Common.FLOAT); + result.newColumnForExport(SpeciesRow.PROPERTY_RTP_UNDEFINED_A, Common.DOUBLE); result.newColumnForExport(SpeciesRow.PROPERTY_RTP_UNDEFINED_B, Common.FLOAT); return result; } @@ -119,11 +119,11 @@ public class SpeciesRowModel extends AbstractTuttiImportExportModel<SpeciesRow> result.newMandatoryColumn(SpeciesRow.PROPERTY_WEIGHT_ENABLED, Common.PRIMITIVE_BOOLEAN); result.newMandatoryColumn(SpeciesRow.PROPERTY_COUNT_IF_NO_FREQUENCY_ENABLED, Common.PRIMITIVE_BOOLEAN); result.newMandatoryColumn(SpeciesRow.PROPERTY_CALCIFY_SAMPLE_ENABLED, Common.PRIMITIVE_BOOLEAN); - result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_MALE_A, Common.FLOAT); + result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_MALE_A, Common.DOUBLE); result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_MALE_B, Common.FLOAT); - result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_FEMALE_A, Common.FLOAT); + result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_FEMALE_A, Common.DOUBLE); result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_FEMALE_B, Common.FLOAT); - result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_UNDEFINED_A, Common.FLOAT); + result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_UNDEFINED_A, Common.DOUBLE); result.newOptionalColumn(SpeciesRow.PROPERTY_RTP_UNDEFINED_B, Common.FLOAT); return result; } 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 23c8a02..0d885b8 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 @@ -325,8 +325,13 @@ tutti.service.persistence.openArchive.error= tutti.service.protocol.export.benthos.error= tutti.service.protocol.export.caracteristics.all.error= tutti.service.protocol.export.caracteristics.protocol.error= +tutti.service.protocol.export.cps.error= +tutti.service.protocol.export.cps.interval.error= tutti.service.protocol.export.species.error= 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.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 f8d3802..0af8d17 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 @@ -287,8 +287,12 @@ tutti.service.persistence.openArchive.error=Erreur lors de l'ouverture de l'arch tutti.service.protocol.export.benthos.error=Erreur lors de l'export du benthos dans le fichier %s tutti.service.protocol.export.caracteristics.all.error=Erreur lors de l'export des caractéristiques dans le fichier %s tutti.service.protocol.export.caracteristics.protocol.error=Erreur lors de l'export des caractéristiques du protocole dans le fichier %s +tutti.service.protocol.export.cps.error=Erreur lors de l'export de l'algorithme de prélèvements des pièces calcifiées dans le fichier %s tutti.service.protocol.export.species.error=Erreur lors de l'export des espèces dans le fichier %s tutti.service.protocol.import.benthos.error=Erreur lors de l'import du benthos du protocole %1s du fichier %2s +tutti.service.protocol.import.cps.error= +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.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 diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java index caaef25..a37739d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java @@ -27,6 +27,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; import fr.ifremer.tutti.persistence.entities.TuttiEntities; import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRow; import fr.ifremer.tutti.persistence.entities.protocol.OperationFieldMappingRow; @@ -42,6 +43,7 @@ import fr.ifremer.tutti.ui.swing.content.protocol.zones.models.StrataUIModel; import fr.ifremer.tutti.ui.swing.content.protocol.zones.models.SubStrataUIModel; import fr.ifremer.tutti.ui.swing.content.protocol.zones.models.ZoneUIModel; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiBeanUIModel; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -212,6 +214,61 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, public TuttiProtocol toEntity() { TuttiProtocol result = newEntity(); toBeanBinder.copyExcluding(this, result, PROPERTY_ZONE); + + Collection<EditProtocolCaracteristicsRowModel> protocolCaracteristicMappingRows = getCaracteristicMappingRows(); + List<CaracteristicMappingRow> caracteristicMappingRows = new ArrayList<CaracteristicMappingRow>(); + for (EditProtocolCaracteristicsRowModel row : protocolCaracteristicMappingRows) { + if (row.isValid()) { + caracteristicMappingRows.add(row.toEntity()); + } + } + result.setCaracteristicMapping(caracteristicMappingRows); + + List<EditProtocolOperationFieldsRowModel> protocolOperationFieldMappingRows = getOperationFieldMappingRows(); + List<OperationFieldMappingRow> operationFieldMappingRows = new ArrayList<OperationFieldMappingRow>(); + for (EditProtocolOperationFieldsRowModel row : protocolOperationFieldMappingRows) { + if (StringUtils.isNotBlank(row.getField()) && StringUtils.isNotBlank(row.getImportColumn()) + && row.isValid()) { + operationFieldMappingRows.add(row.toEntity()); + } + } + result.setOperationFieldMapping(operationFieldMappingRows); + + // map the cps rows by species row + Multimap<EditProtocolSpeciesRowModel, CalcifiedPiecesSamplingEditorRowModel> cpsRowsBySpecies = + Multimaps.index(getCpsRows(), input -> input.getProtocolSpecies()); + + // get the species protocols from the table + List<SpeciesProtocol> speciesProtocols = Lists.newArrayList(); + + for (EditProtocolSpeciesRowModel row : getSpeciesRow()) { + if (row.isValid()) { + SpeciesProtocol protocol = row.toEntity(); + speciesProtocols.add(protocol); + + Collection<CalcifiedPiecesSamplingEditorRowModel> cpsRows = cpsRowsBySpecies.get(row); + protocol.setCalcifiedPiecesSamplingDefinition(cpsRows.stream() + .map(CalcifiedPiecesSamplingEditorRowModel::toEntity) + .collect(Collectors.toList())); + } + } + result.setSpecies(speciesProtocols); + + List<SpeciesProtocol> benthosProtocols = Lists.newArrayList(); + + for (EditProtocolSpeciesRowModel row : getBenthosRow()) { + if (row.isValid()) { + SpeciesProtocol protocol = row.toEntity(); + benthosProtocols.add(protocol); + + Collection<CalcifiedPiecesSamplingEditorRowModel> cpsRows = cpsRowsBySpecies.get(row); + protocol.setCalcifiedPiecesSamplingDefinition(cpsRows.stream() + .map(CalcifiedPiecesSamplingEditorRowModel::toEntity) + .collect(Collectors.toList())); + } + } + result.setBenthos(benthosProtocols); + Collection<Zone> zoneModels = getZone().stream() .map(zone -> { ZoneUIModel zoneUIModel = (ZoneUIModel) zone; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolBenthosAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolBenthosAction.java index 082fa96..e543045 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolBenthosAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolBenthosAction.java @@ -55,6 +55,10 @@ public class ImportProtocolBenthosAction extends LongActionSupport<EditProtocolU private File file; + private TuttiProtocol protocol; + + private List<Species> notImportedBenthos; + public ImportProtocolBenthosAction(EditProtocolUIHandler handler) { super(handler, false); } @@ -79,12 +83,6 @@ public class ImportProtocolBenthosAction extends LongActionSupport<EditProtocolU } @Override - public void releaseAction() { - file = null; - super.releaseAction(); - } - - @Override public void doAction() throws Exception { Preconditions.checkNotNull(file); if (log.isInfoEnabled()) { @@ -94,17 +92,21 @@ public class ImportProtocolBenthosAction extends LongActionSupport<EditProtocolU EditProtocolUIModel model = getModel(); // bind to a protocol - TuttiProtocol protocol = model.toEntity(); + protocol = model.toEntity(); // import ProtocolImportExportService service = getContext().getTuttiProtocolImportExportService(); - List<Species> notImportedBenthos = - service.importProtocolBenthos(file, - protocol, - model.getAllCaracteristic(), - model.getAllReferentSpeciesByTaxonId()); + notImportedBenthos = service.importProtocolBenthos(file, + protocol, + model.getAllCaracteristic(), + model.getAllReferentSpeciesByTaxonId()); + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); // build rows from imported+merged protocol // (will also remove all synonyms of species referent used) @@ -118,7 +120,7 @@ public class ImportProtocolBenthosAction extends LongActionSupport<EditProtocolU getUI().getBenthosComboBox().getHandler().reset(); // update rows in model - model.setBenthosRow(rows); + getModel().setBenthosRow(rows); getHandler().getBenthosTableModel().setRows(rows); @@ -160,4 +162,12 @@ public class ImportProtocolBenthosAction extends LongActionSupport<EditProtocolU ); } } + + @Override + public void releaseAction() { + file = null; + protocol = null; + notImportedBenthos = null; + super.releaseAction(); + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolSpeciesAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolSpeciesAction.java index 63f914e..b17f66a 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolSpeciesAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/ImportProtocolSpeciesAction.java @@ -55,6 +55,10 @@ public class ImportProtocolSpeciesAction extends LongActionSupport<EditProtocolU private File file; + private TuttiProtocol protocol; + + private List<Species> notImportedSpecies; + public ImportProtocolSpeciesAction(EditProtocolUIHandler handler) { super(handler, false); } @@ -79,12 +83,6 @@ public class ImportProtocolSpeciesAction extends LongActionSupport<EditProtocolU } @Override - public void releaseAction() { - file = null; - super.releaseAction(); - } - - @Override public void doAction() throws Exception { Preconditions.checkNotNull(file); if (log.isInfoEnabled()) { @@ -94,17 +92,21 @@ public class ImportProtocolSpeciesAction extends LongActionSupport<EditProtocolU EditProtocolUIModel model = getModel(); // bind to a protocol - TuttiProtocol protocol = model.toEntity(); + protocol = model.toEntity(); // import ProtocolImportExportService service = getContext().getTuttiProtocolImportExportService(); - List<Species> notImportedSpecies = - service.importProtocolSpecies(file, - protocol, - model.getAllCaracteristic(), - model.getAllReferentSpeciesByTaxonId()); + notImportedSpecies = service.importProtocolSpecies(file, + protocol, + model.getAllCaracteristic(), + model.getAllReferentSpeciesByTaxonId()); + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); // build rows from imported+merged protocol // (will also remove all synonyms of species referent used) @@ -118,7 +120,7 @@ public class ImportProtocolSpeciesAction extends LongActionSupport<EditProtocolU getUI().getBenthosComboBox().getHandler().reset(); // update rows in model - model.setSpeciesRow(rows); + getModel().setSpeciesRow(rows); getHandler().getSpeciesTableModel().setRows(rows); @@ -160,4 +162,12 @@ public class ImportProtocolSpeciesAction extends LongActionSupport<EditProtocolU ); } } + + @Override + public void releaseAction() { + file = null; + protocol = null; + notImportedSpecies = null; + super.releaseAction(); + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveBenthosProtocolAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveBenthosProtocolAction.java index ef2ea7e..3152a8a 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveBenthosProtocolAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveBenthosProtocolAction.java @@ -157,8 +157,10 @@ public class RemoveBenthosProtocolAction extends LongActionSupport<EditProtocolU getModel().getBenthosRow().removeAll(removedRows); // remove the protocolSpecies from the cps table or combobox - updateCpsTable(); - updateCpsEditorCombo(); + if (!cpsRowsToDelete.isEmpty()) { + updateCpsTable(); + updateCpsEditorCombo(); + } // fire table data changed handler.getBenthosTableModel().fireTableDataChanged(); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveSpeciesProtocolAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveSpeciesProtocolAction.java index 627a50b..4d5754d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveSpeciesProtocolAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/RemoveSpeciesProtocolAction.java @@ -154,8 +154,10 @@ public class RemoveSpeciesProtocolAction extends LongActionSupport<EditProtocolU getModel().getSpeciesRow().removeAll(removedRows); // remove the protocolSpecies from the cps table or combobox - updateCpsTable(); - updateCpsEditorCombo(); + if (!cpsRowsToDelete.isEmpty()) { + updateCpsTable(); + updateCpsEditorCombo(); + } // fire table data changed handler.getSpeciesTableModel().fireTableDataChanged(); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/SaveProtocolAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/SaveProtocolAction.java index f6b0448..4be6b8f 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/SaveProtocolAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/actions/SaveProtocolAction.java @@ -79,61 +79,7 @@ public class SaveProtocolAction extends LongActionSupport<EditProtocolUIModel, E TuttiProtocol bean = model.toEntity(); - Collection<EditProtocolCaracteristicsRowModel> protocolCaracteristicMappingRows = model.getCaracteristicMappingRows(); - List<CaracteristicMappingRow> caracteristicMappingRows = new ArrayList<CaracteristicMappingRow>(); - for (EditProtocolCaracteristicsRowModel row : protocolCaracteristicMappingRows) { - if (row.isValid()) { - caracteristicMappingRows.add(row.toEntity()); - } - } - bean.setCaracteristicMapping(caracteristicMappingRows); - - List<EditProtocolOperationFieldsRowModel> protocolOperationFieldMappingRows = model.getOperationFieldMappingRows(); - List<OperationFieldMappingRow> operationFieldMappingRows = new ArrayList<OperationFieldMappingRow>(); - for (EditProtocolOperationFieldsRowModel row : protocolOperationFieldMappingRows) { - if (StringUtils.isNotBlank(row.getField()) && StringUtils.isNotBlank(row.getImportColumn()) - && row.isValid()) { - operationFieldMappingRows.add(row.toEntity()); - } - } - bean.setOperationFieldMapping(operationFieldMappingRows); - - // map the cps rows by species row - Multimap<EditProtocolSpeciesRowModel, CalcifiedPiecesSamplingEditorRowModel> cpsRowsBySpecies = - Multimaps.index(model.getCpsRows(), input -> input.getProtocolSpecies()); - - // get the species protocols from the table - List<SpeciesProtocol> speciesProtocols = Lists.newArrayList(); - - for (EditProtocolSpeciesRowModel row : model.getSpeciesRow()) { - if (row.isValid()) { - SpeciesProtocol protocol = row.toEntity(); - speciesProtocols.add(protocol); - - //TODO check validity - Collection<CalcifiedPiecesSamplingEditorRowModel> cpsRows = cpsRowsBySpecies.get(row); - protocol.setCalcifiedPiecesSamplingDefinition(cpsRows.stream() - .map(CalcifiedPiecesSamplingEditorRowModel::toEntity) - .collect(Collectors.toList())); - } - } - bean.setSpecies(speciesProtocols); - List<SpeciesProtocol> benthosProtocols = Lists.newArrayList(); - - for (EditProtocolSpeciesRowModel row : model.getBenthosRow()) { - if (row.isValid()) { - SpeciesProtocol protocol = row.toEntity(); - benthosProtocols.add(protocol); - - //TODO check validity - Collection<CalcifiedPiecesSamplingEditorRowModel> cpsRows = cpsRowsBySpecies.get(row); - protocol.setCalcifiedPiecesSamplingDefinition(cpsRows.stream() - .map(CalcifiedPiecesSamplingEditorRowModel::toEntity) - .collect(Collectors.toList())); - } - } - bean.setBenthos(benthosProtocols); if (log.isInfoEnabled()) { diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx index cbbbcfd..0c77749 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx @@ -32,6 +32,11 @@ <JMenuItem id='deleteSpeciesMenu'/> </JPopupMenu> + <JPanel id='cpsActions' layout="{new GridLayout()}" constraints='BorderLayout.NORTH'> + <JButton id='importCpsButton'/> + <JButton id='exportCpsButton'/> + </JPanel> + <Table fill='both' constraints='BorderLayout.CENTER'> <row fill='both'> diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss index 8d915a6..cf1bf8d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss @@ -2,6 +2,24 @@ BeanFilterableComboBox { showReset: true; } +#importCpsButton { + actionIcon: import; + text: "tutti.editProtocol.action.importProtocolCps"; + toolTipText: "tutti.editProtocol.action.importProtocolCps.tip"; + i18nMnemonic: "tutti.editProtocol.action.importProtocolCps.mnemonic"; + _applicationAction: {fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions.ImportProtocolCpsAction.class}; + _help: {"tutti.editProtocol.action.importProtocolCps.help"}; +} + +#exportCpsButton { + actionIcon: export; + text: "tutti.editProtocol.action.exportProtocolCps"; + toolTipText: "tutti.editProtocol.action.exportProtocolCps.tip"; + i18nMnemonic: "tutti.editProtocol.action.exportProtocolCps.mnemonic"; + _applicationAction: {fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions.ExportProtocolCpsAction.class}; + _help: {"tutti.editProtocol.action.exportProtocolCps.help"}; +} + #speciesComboBox { enabled: {!speciesComboBox.isEmpty()}; toolTipText: "tutti.editCps.field.species.tip"; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java index 7e622a9..867d6df 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java @@ -28,7 +28,6 @@ import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.TreeSet; @@ -116,13 +115,13 @@ public class CalcifiedPiecesSamplingEditorUIHandler extends AbstractTuttiUIHandl // at the very end, set rows to model getModel().addPropertyChangeListener(EditProtocolUIModel.PROPERTY_CPS_ROWS, evt -> { - Collection<CalcifiedPiecesSamplingEditorRowModel> rows = - (Collection<CalcifiedPiecesSamplingEditorRowModel>) evt.getNewValue(); + List<CalcifiedPiecesSamplingEditorRowModel> rows = + (List<CalcifiedPiecesSamplingEditorRowModel>) evt.getNewValue(); for (CalcifiedPiecesSamplingEditorRowModel row : rows) { row.removePropertyChangeListener(rowChangeListener); row.addPropertyChangeListener(rowChangeListener); } - tableModel.setRows(getModel().getCpsRows()); + tableModel.setRows(rows); tableModel.fireTableDataChanged(); getUI().getSpeciesComboBox().removeItems(rows.stream() diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ExportProtocolCpsAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ExportProtocolCpsAction.java new file mode 100644 index 0000000..944694b --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ExportProtocolCpsAction.java @@ -0,0 +1,116 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions; + +/* + * #%L + * Tutti :: UI + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.service.protocol.ProtocolImportExportService; +import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorRowModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUI; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUIHandler; +import fr.ifremer.tutti.ui.swing.util.actions.LongActionSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; + +import static org.nuiton.i18n.I18n.t; + +/** + * To export protocol cps. + * + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class ExportProtocolCpsAction extends LongActionSupport<EditProtocolUIModel, + CalcifiedPiecesSamplingEditorUI, + CalcifiedPiecesSamplingEditorUIHandler> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ExportProtocolCpsAction.class); + + private File file; + + public ExportProtocolCpsAction(CalcifiedPiecesSamplingEditorUIHandler handler) { + super(handler, true); + } + + @Override + public boolean prepareAction() throws Exception { + + boolean doAction = super.prepareAction(); + + if (doAction) { + + // choose file to export + file = saveFile( + "tuttiProtocol-" + getModel().getName() + "-cps", + "csv", + t("tutti.editProtocol.title.choose.cpsExportFile"), + t("tutti.editProtocol.action.exportProtocolCpsFile"), + "^.*\\.csv", t("tutti.common.file.csv") + ); + doAction = file != null; + } + return doAction; + } + + @Override + public void doAction() throws Exception { + Preconditions.checkNotNull(file); + if (log.isInfoEnabled()) { + log.info("Will export protocol cps to file: " + file); + } + + EditProtocolUIModel model = getModel(); + + // build species protocol to export + + Multimap<SpeciesProtocol, CalcifiedPiecesSamplingDefinition> cps = ArrayListMultimap.create(); + for (CalcifiedPiecesSamplingEditorRowModel row : model.getCpsRows()) { + cps.put(row.getProtocolSpecies().toEntity(), row.toEntity()); + } + + ProtocolImportExportService service = getContext().getTuttiProtocolImportExportService(); + + service.exportCalcifiedPiecesSamplings(file, cps, getModel().getAllReferentSpeciesByTaxonId()); + + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); + sendMessage(t("tutti.flash.info.cps.exported.from.protocol", file)); + } + + @Override + public void releaseAction() { + file = null; + super.releaseAction(); + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ImportProtocolCpsAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ImportProtocolCpsAction.java new file mode 100644 index 0000000..594cc0f --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/ImportProtocolCpsAction.java @@ -0,0 +1,179 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions; + +/* + * #%L + * Tutti :: UI + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.DecoratorService; +import fr.ifremer.tutti.service.protocol.ProtocolImportExportService; +import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolSpeciesRowModel; +import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorRowModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUI; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUIHandler; +import fr.ifremer.tutti.ui.swing.util.actions.LongActionSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.nuiton.i18n.I18n.t; + +/** + * To import protocol cps. + * + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class ImportProtocolCpsAction extends LongActionSupport<EditProtocolUIModel, CalcifiedPiecesSamplingEditorUI, CalcifiedPiecesSamplingEditorUIHandler> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ImportProtocolCpsAction.class); + + private File file; + + private TuttiProtocol protocol; + + private Set<Species> notImportedSpecies; + + public ImportProtocolCpsAction(CalcifiedPiecesSamplingEditorUIHandler handler) { + super(handler, false); + } + + @Override + public boolean prepareAction() throws Exception { + + boolean doAction = super.prepareAction(); + + if (doAction) { + + // choose file to import + file = chooseFile( + t("tutti.editProtocol.title.choose.cpsImportFile"), + t("tutti.editProtocol.action.importProtocolCpsFile"), + "^.*\\.csv", t("tutti.common.file.csv") + ); + + doAction = file != null; + } + return doAction; + } + + @Override + public void doAction() throws Exception { + Preconditions.checkNotNull(file); + if (log.isInfoEnabled()) { + log.info("Will import protocol cps file: " + file); + } + + EditProtocolUIModel model = getModel(); + + // bind to a protocol + protocol = model.toEntity(); + + // import + ProtocolImportExportService service = + getContext().getTuttiProtocolImportExportService(); + + notImportedSpecies = service.importCalcifiedPiecesSamplings(file, + protocol, + model.getAllReferentSpeciesByTaxonId()); + + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); + + // add all the cps rows + Collection<SpeciesProtocol> allSpeciesProtocol = new ArrayList<>(); + if (!protocol.isSpeciesEmpty()) { + allSpeciesProtocol.addAll(protocol.getSpecies()); + } + if (!protocol.isBenthosEmpty()) { + allSpeciesProtocol.addAll(protocol.getBenthos()); + } + + Collection<EditProtocolSpeciesRowModel> speciesRows = new ArrayList<>(); + speciesRows.addAll(getModel().getSpeciesRow()); + speciesRows.addAll(getModel().getBenthosRow()); + Map<Integer, EditProtocolSpeciesRowModel> rowsByRefTaxId = speciesRows.stream() + .collect(Collectors.toMap(EditProtocolSpeciesRowModel::getSpeciesReferenceTaxonId, + Function.identity())); + + List<CalcifiedPiecesSamplingEditorRowModel> cpsRows = new ArrayList<>(); + + allSpeciesProtocol.forEach(speciesProtocol -> { + + Collection<CalcifiedPiecesSamplingDefinition> cpsDefs = speciesProtocol.getCalcifiedPiecesSamplingDefinition(); + if (cpsDefs != null) { + cpsDefs.forEach(def -> { + CalcifiedPiecesSamplingEditorRowModel cpsRow = new CalcifiedPiecesSamplingEditorRowModel(); + cpsRow.fromEntity(def); + cpsRow.setProtocolSpecies(rowsByRefTaxId.get(speciesProtocol.getSpeciesReferenceTaxonId())); + cpsRows.add(cpsRow); + }); + } + }); + + getModel().setCpsRows(cpsRows); + + if (log.isInfoEnabled()) { + log.info("not imported cps : " + notImportedSpecies.size() + "\n" + notImportedSpecies); + } + + sendMessage(t("tutti.flash.info.cps.imported.in.protocol", file)); + + if (!notImportedSpecies.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (Species sp : notImportedSpecies) { + sb.append("<li>" + decorate(sp, DecoratorService.FROM_PROTOCOL) + "</li>"); + } + displayWarningMessage( + t("tutti.editProtocol.action.importProtocolCps.speciesNotImported.title"), + "<html><body>" + + t("tutti.editProtocol.action.importProtocolSpecies.speciesNotImported", sb.toString()) + + "</body></html>" + ); + } + } + + @Override + public void releaseAction() { + file = null; + protocol = null; + notImportedSpecies = null; + super.releaseAction(); + } +} diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties index 1463c55..9facbd3 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties @@ -1061,6 +1061,10 @@ tutti.editProtocol.action.exportProtocolCaracteristic= tutti.editProtocol.action.exportProtocolCaracteristic.mnemonic= tutti.editProtocol.action.exportProtocolCaracteristic.tip= tutti.editProtocol.action.exportProtocolCaracteristicFile= +tutti.editProtocol.action.exportProtocolCps= +tutti.editProtocol.action.exportProtocolCps.mnemonic= +tutti.editProtocol.action.exportProtocolCps.tip= +tutti.editProtocol.action.exportProtocolCpsFile= tutti.editProtocol.action.exportProtocolSpecies= tutti.editProtocol.action.exportProtocolSpecies.mnemonic= tutti.editProtocol.action.exportProtocolSpecies.tip= @@ -1083,10 +1087,16 @@ tutti.editProtocol.action.importProtocolCaracteristicFile= tutti.editProtocol.action.importProtocolColumns= tutti.editProtocol.action.importProtocolColumns.mnemonic= tutti.editProtocol.action.importProtocolColumns.tip= +tutti.editProtocol.action.importProtocolCps= +tutti.editProtocol.action.importProtocolCps.mnemonic= +tutti.editProtocol.action.importProtocolCps.speciesNotImported.title= +tutti.editProtocol.action.importProtocolCps.tip= +tutti.editProtocol.action.importProtocolCpsFile= tutti.editProtocol.action.importProtocolSpecies= tutti.editProtocol.action.importProtocolSpecies.mnemonic= tutti.editProtocol.action.importProtocolSpecies.speciesInBenthos= tutti.editProtocol.action.importProtocolSpecies.speciesInBenthos.title= +tutti.editProtocol.action.importProtocolSpecies.speciesNotImported= tutti.editProtocol.action.importProtocolSpecies.tip= tutti.editProtocol.action.importProtocolSpeciesFile= tutti.editProtocol.action.importSpecies.speciesInBenthos= @@ -1182,6 +1192,8 @@ tutti.editProtocol.title.choose.benthosExportFile= tutti.editProtocol.title.choose.benthosImportFile= tutti.editProtocol.title.choose.caracteristicExportFile= tutti.editProtocol.title.choose.caracteristicImportFile= +tutti.editProtocol.title.choose.cpsExportFile= +tutti.editProtocol.title.choose.cpsImportFile= tutti.editProtocol.title.choose.speciesExportFile= tutti.editProtocol.title.choose.speciesImportFile= tutti.editProtocol.title.create.protocol= @@ -1553,6 +1565,8 @@ tutti.flash.info.caracteristic.add.to.protocol= tutti.flash.info.caracteristic.imported.in.protocol= tutti.flash.info.caracteristicMapping.remove.from.protocol= tutti.flash.info.caractristic.exported.from.protocol= +tutti.flash.info.cps.exported.from.protocol= +tutti.flash.info.cps.imported.in.protocol= tutti.flash.info.cruiseCreated= tutti.flash.info.cruiseSaved= tutti.flash.info.db.closed= diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index 7bf8c08..d20fb7d 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -1014,6 +1014,10 @@ tutti.editProtocol.action.exportProtocolCaracteristic=Exporter les caractéristi tutti.editProtocol.action.exportProtocolCaracteristic.mnemonic=c tutti.editProtocol.action.exportProtocolCaracteristic.tip=Exporter les caractéristiques du protocole tutti.editProtocol.action.exportProtocolCaracteristicFile=Exporter +tutti.editProtocol.action.exportProtocolCps=Exporter un algorithme de prélèvement +tutti.editProtocol.action.exportProtocolCps.mnemonic=E +tutti.editProtocol.action.exportProtocolCps.tip=Importer un algorithme de prélèvement de pièces calcifiées dans le protocole +tutti.editProtocol.action.exportProtocolCpsFile=Exporter tutti.editProtocol.action.exportProtocolSpecies=Exporter les espèces tutti.editProtocol.action.exportProtocolSpecies.mnemonic=è tutti.editProtocol.action.exportProtocolSpecies.tip=Exporter les espèces du protocole @@ -1034,10 +1038,16 @@ tutti.editProtocol.action.importProtocolCaracteristicFile=Importer tutti.editProtocol.action.importProtocolColumns=Importer le fichier de paramètres tutti.editProtocol.action.importProtocolColumns.mnemonic=c tutti.editProtocol.action.importProtocolColumns.tip=Importer le fichier de paramètres +tutti.editProtocol.action.importProtocolCps=Importer un algorithme de prélèvement +tutti.editProtocol.action.importProtocolCps.mnemonic=I +tutti.editProtocol.action.importProtocolCps.speciesNotImported.title=Espèces non importées +tutti.editProtocol.action.importProtocolCps.tip=Importer un algorithme de prélèvement de pièces calcifiées dans le protocole +tutti.editProtocol.action.importProtocolCpsFile=Importer tutti.editProtocol.action.importProtocolSpecies=Importer les espèces tutti.editProtocol.action.importProtocolSpecies.mnemonic=é tutti.editProtocol.action.importProtocolSpecies.speciesInBenthos=Les espèces suivantes n'ont pas été importées car elles sont déjà présentes dans le benthos \:<ul>%s</ul> tutti.editProtocol.action.importProtocolSpecies.speciesInBenthos.title=Espèces non importées +tutti.editProtocol.action.importProtocolSpecies.speciesNotImported=Les espèces suivantes n'ont pas été importées car elles ne sont pas dans le protocole ou sont déjà définies dans l'algorithme \:<ul>%s</ul> tutti.editProtocol.action.importProtocolSpecies.tip=Importer les espèces dans le protocole tutti.editProtocol.action.importProtocolSpeciesFile=Importer tutti.editProtocol.action.loadImportColumns.success=%s colonnes importées avec succès @@ -1121,6 +1131,8 @@ tutti.editProtocol.title.choose.benthosExportFile=Exporter les benthos tutti.editProtocol.title.choose.benthosImportFile=Importer les benthos tutti.editProtocol.title.choose.caracteristicExportFile=Exporter les caractéristiques tutti.editProtocol.title.choose.caracteristicImportFile=Importer les caractéristiques +tutti.editProtocol.title.choose.cpsExportFile=Exporter l'algorithme de prélèvement +tutti.editProtocol.title.choose.cpsImportFile=Importer un algorithme de prélèvement tutti.editProtocol.title.choose.speciesExportFile=Exporter les espèces tutti.editProtocol.title.choose.speciesImportFile=Importer les espèces tutti.editProtocol.title.create.protocol=Créer un nouveau protocole de saisie @@ -1457,6 +1469,8 @@ tutti.flash.info.caracteristic.add.to.protocol=La caractéristique <strong>%s</s tutti.flash.info.caracteristic.imported.in.protocol=Caractéristiques importées dans le protocole depuis le fichier <strong>%s</strong>. tutti.flash.info.caracteristicMapping.remove.from.protocol=Les caractéristiques ont été retirées du protocole. tutti.flash.info.caractristic.exported.from.protocol=Caractéristiques du protocole exportées dans le fichier <strong>%s</strong>. +tutti.flash.info.cps.exported.from.protocol=Algorithme de prélèvement du protocole exporté dans le fichier <strong>%s</strong>. +tutti.flash.info.cps.imported.in.protocol=\=Algorithme de prélèvement importé dans le protocole depuis le fichier <strong>%s</strong>. tutti.flash.info.cruiseCreated=La campagne <strong>%s</strong> a été créée. tutti.flash.info.cruiseSaved=La campagne <strong>%s</strong> a été enregistrée. tutti.flash.info.db.closed=La base <strong>%s</strong> est fermée. -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.