Author: tchemit Date: 2013-02-25 21:44:07 +0100 (Mon, 25 Feb 2013) New Revision: 476 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/476 Log: - prepare release - add clearAllCaches method - fix db referential synchronize Modified: trunk/pom.xml trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistence.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/batch/ScientificCruiseCatchBatchValidator.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/batch/CatchBatchValidatorReadTest.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java trunk/tutti-ui-swing/pom.xml trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/SelectOtherSpeciesAction.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/TuttiCollectionUniqueKeyValidator.java Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/pom.xml 2013-02-25 20:44:07 UTC (rev 476) @@ -213,6 +213,12 @@ <classifier>tests</classifier> </dependency> + <dependency> + <groupId>org.apache.struts.xwork</groupId> + <artifactId>xwork-core</artifactId> + <version>2.3.7</version> + </dependency> + <!-- librairie Jaxx --> <dependency> <groupId>org.nuiton.jaxx</groupId> Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistence.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistence.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistence.java 2013-02-25 20:44:07 UTC (rev 476) @@ -44,6 +44,8 @@ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.Vessel; import fr.ifremer.tutti.persistence.entities.referential.Zone; +import org.hibernate.event.EvictEvent; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -63,6 +65,12 @@ String getImplementationName(); + /** + * To clear all caches. + * @since 1.0.1 + */ + void clearAllCaches(); + //------------------------------------------------------------------------// //-- Referential methods --// //------------------------------------------------------------------------// Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java 2013-02-25 20:44:07 UTC (rev 476) @@ -27,6 +27,7 @@ import com.google.common.collect.Maps; import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationException; +import fr.ifremer.adagio.core.service.technical.CacheService; import fr.ifremer.tutti.persistence.entities.data.AccidentalBatch; import fr.ifremer.tutti.persistence.entities.data.BenthosBatch; import fr.ifremer.tutti.persistence.entities.data.CatchBatch; @@ -112,12 +113,20 @@ @Autowired protected ProtocolPersistenceService protocolService; + @Autowired + protected CacheService cacheService; + @Override public String getImplementationName() { return "Persistence Adagio implementation"; } @Override + public void clearAllCaches() { + cacheService.clearAllCaches(); + } + + @Override public void init() { if (log.isInfoEnabled()) { log.info("Open persistence driver " + getImplementationName()); Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java 2013-02-25 20:44:07 UTC (rev 476) @@ -62,6 +62,11 @@ } @Override + public void clearAllCaches() { + throw new RuntimeException("method not implemented"); + } + + @Override public List<Zone> getAllProgramZone() { throw new RuntimeException("method not implemented"); } Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/batch/ScientificCruiseCatchBatchValidator.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/batch/ScientificCruiseCatchBatchValidator.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/batch/ScientificCruiseCatchBatchValidator.java 2013-02-25 20:44:07 UTC (rev 476) @@ -1,253 +1,278 @@ -package fr.ifremer.tutti.persistence.service.batch; - -import static org.nuiton.i18n.I18n._; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Component; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import fr.ifremer.adagio.core.dao.data.batch.Batch; -import fr.ifremer.adagio.core.dao.data.batch.CatchBatch; -import fr.ifremer.adagio.core.dao.data.batch.CatchBatchExtendDao; -import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; -import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchQuickFix; -import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationError; -import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidator; -import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement; -import fr.ifremer.tutti.persistence.service.BatchPersistenceService; -import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; -import fr.ifremer.tutti.persistence.service.TuttiEnumerationFile; - -@Component(value = "scientificCruiseCatchBatchValidator") -public class ScientificCruiseCatchBatchValidator implements CatchBatchValidator { - - /** Logger. */ - private static final Log log = - LogFactory.getLog(ScientificCruiseCatchBatchValidator.class); - - @Autowired - protected BatchPersistenceService batchService; - - @Autowired - protected ReferentialPersistenceService referentialService; - - @Autowired - protected CatchBatchExtendDao catchBatchDao; - - @Autowired - protected TuttiEnumerationFile enumeration; - - public ScientificCruiseCatchBatchValidator() { - } - - @Override - public boolean isEnable(fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch) { - // Apply validation only on catch batch for fishingOperation - return (catchBatch.getFishingOperation() != null); - } - - @Override - public List<CatchBatchValidationError> validate(fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch) { - List<CatchBatchValidationError> errors = Lists.newArrayList(); - validate(catchBatch.getChildBatchs(), errors, 1); - return errors; - } - - // ------------------------------------------------------------------------// - // -- Internal methods --// - // ------------------------------------------------------------------------// - - protected void validate(Collection<Batch> batchs, List<CatchBatchValidationError> errors, int treeLevel) { - - // Vrac - SortingBatch vracBatch = catchBatchDao.getSortingBatch(batchs, - "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_VRAC_ID); - if (vracBatch == null) { - addError(errors, "tutti.persistence.batch.validation.vracNotFound", null); - } else { - // Vrac > Species - SortingBatch speciesBatch = catchBatchDao.getSortingBatch(vracBatch.getChildBatchs(), - "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, - enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); - if (speciesBatch == null) { - addError(errors, "tutti.persistence.batch.validation.vracSpeciesNotFound", null); - } else { - // Vrac > Species > Inert - SortingBatch inertBatch = catchBatchDao.getSortingBatch(speciesBatch.getChildBatchs(), - "referenceTaxonId", enumeration.REFERENCE_TAXON_ID_INERT); - if (inertBatch == null) { - addWarning(errors, "tutti.persistence.batch.validation.vracSpeciesInertNotFound"); - } - - // Vrac > Species > Alive no itemized - SortingBatch livingNotItemizedBatch = catchBatchDao.getSortingBatch(speciesBatch.getChildBatchs(), - "referenceTaxonId", enumeration.REFERENCE_TAXON_ID_LIFE); - if (livingNotItemizedBatch == null) { - addWarning(errors, "tutti.persistence.batch.validation.vracSpeciesLifeNotFound"); - } - } - - // TODO : Benthos, Plancton... - } - - // Hors Vrac - SortingBatch horsVracBatch = catchBatchDao.getSortingBatch(batchs, - "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, - enumeration.QUALITATIVE_HORS_VRAC_ID); - if (horsVracBatch == null) { - addWarning(errors, "tutti.persistence.batch.validation.horsVracSpeciesNotFound"); - } else { - // Hors Vrac > Species - SortingBatch speciesBatch = catchBatchDao.getSortingBatch(horsVracBatch.getChildBatchs(), - "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, - enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); - if (speciesBatch == null) { - addWarning(errors, "tutti.persistence.batch.validation.horsVracSpeciesNotFound"); - } - - // TODO : Benthos, Plancton... - } - - // Unsorted - SortingBatch unsortedBatch = catchBatchDao.getSortingBatch(batchs, - "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, - enumeration.QUALITATIVE_UNSORTED_ID); - if (unsortedBatch == null) { - addWarning(errors, "tutti.persistence.batch.validation.unsortedNotFound"); - } - - // May be, the tree is an old structure - if (vracBatch == null && horsVracBatch == null && unsortedBatch == null) { - boolean allBatchHasSpecies = true; - boolean allBatchHasVrac = true; - boolean someBatchHasSortingMeasurement = false; - for (Iterator<Batch> iterator = batchs.iterator(); iterator.hasNext();) { - SortingBatch batch = (SortingBatch) iterator.next(); - if (allBatchHasSpecies && batch.getReferenceTaxon() == null) { - allBatchHasSpecies = false; - break; - } - if (allBatchHasVrac && batch.getSortingMeasurements() != null) { - if (batch.getSortingMeasurements().size() > 1) { - allBatchHasVrac = false; - someBatchHasSortingMeasurement = true; - } - else if (batch.getSortingMeasurements().size() == 1) { - someBatchHasSortingMeasurement = true; - SortingMeasurement sm = batch.getSortingMeasurements().iterator().next(); - if (enumeration.PMFM_ID_SORTED_UNSORTED.equals(sm.getPmfm().getId()) == false - || sm.getQualitativeValue() == null - || enumeration.QUALITATIVE_VRAC_ID.equals(sm.getQualitativeValue().getId()) == false) { - allBatchHasVrac = false; - } - } - } - } - if (allBatchHasSpecies && !someBatchHasSortingMeasurement) { - errors.clear(); - addError(errors, "tutti.persistence.batch.validation.onlySpeciesBatchStructure", new CatchBatchQuickFix() { - @Override - public CatchBatch repair(CatchBatch catchBatch) { - return ScientificCruiseCatchBatchValidator.this.repairHistoricalData(catchBatch, false); - } - }); - } - else if (allBatchHasSpecies && someBatchHasSortingMeasurement && allBatchHasVrac) { - errors.clear(); - addError(errors, "tutti.persistence.batch.validation.onlySpeciesBatchStructure", new CatchBatchQuickFix() { - @Override - public CatchBatch repair(CatchBatch catchBatch) { - return ScientificCruiseCatchBatchValidator.this.repairHistoricalData(catchBatch, true); - } - }); - } - } - } - - /** - * Repair tree batch, when only species have been found under the cacth batch. - * This append typically with CGFS cruise. - * @param catchBatch - * @return - */ - protected CatchBatch repairHistoricalData(CatchBatch catchBatch, boolean batchHasVracSortingMeasurement) { - Preconditions.checkNotNull(catchBatch); - Preconditions.checkNotNull(catchBatch.getId()); - Preconditions.checkNotNull(catchBatch.getFishingOperation()); - Preconditions.checkNotNull(catchBatch.getFishingOperation().getId()); - - // Copy catch batch children - Collection<Batch> speciesBatchChilds = Sets.newHashSet(); - speciesBatchChilds.addAll(catchBatch.getChildBatchs()); - catchBatch.setChildBatchs(new HashSet<Batch>()); - - // Clean catch batch - batchService.cleanEntity(catchBatch, true); - - SortingBatch speciesBatch = catchBatchDao.getSortingBatch(catchBatch.getChildBatchs(), - "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_VRAC_ID, - "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); - if (speciesBatch == null) { - throw new DataIntegrityViolationException("Invalid batch tree format. Could not retrieve 'Vrac>Species' batch."); - } - - // For all species batch : set the batch 'Vrac>Species' as new parent - for (Iterator<Batch> iterator = speciesBatchChilds.iterator(); iterator.hasNext();) { - SortingBatch batch = (SortingBatch) iterator.next(); - batch.setParentBatch(speciesBatch); - - if (batchHasVracSortingMeasurement) { - // Remove redundant 'Vrac' sorting measurement - SortingMeasurement sm = catchBatchDao.getSortingMeasurement(batch, enumeration.PMFM_ID_SORTED_UNSORTED, null, false); - batch.getSortingMeasurements().remove(sm); - } - - batch.setExhaustiveInventory(Boolean.TRUE); - - // Add an offset into the rank order, because of special batchs 'Biota' (=live) and 'Inert' - short rankOrder = (short)(batch.getRankOrder().shortValue() + 2); - batch.setRankOrder(rankOrder); - - // Reset comments if set to "taxon" - if (batch.getComments() != null && "taxon".equals(batch.getComments())) { - batch.setComments(null); - } - - speciesBatch.getChildBatchs().add(batch); - } - - // Save mofidifications : - catchBatchDao.update(catchBatch); - - return catchBatch; - } - - protected void addError(List<CatchBatchValidationError> errors, String messageKey, CatchBatchQuickFix quickFix) { - CatchBatchValidationError error = new CatchBatchValidationError( - messageKey, - _(messageKey), - CatchBatchValidationError.GRAVITY_ERROR); - error.setQuickFixes(Lists.newArrayList(quickFix)); - errors.add(error); - } - - protected void addWarning(List<CatchBatchValidationError> errors, String messageKey) { - CatchBatchValidationError error = new CatchBatchValidationError( - messageKey, - _(messageKey), - CatchBatchValidationError.GRAVITY_WARNING); - errors.add(error); - } - -} +package fr.ifremer.tutti.persistence.service.batch; + +/* + * #%L + * Tutti :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 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 static org.nuiton.i18n.I18n._; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Component; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import fr.ifremer.adagio.core.dao.data.batch.Batch; +import fr.ifremer.adagio.core.dao.data.batch.CatchBatch; +import fr.ifremer.adagio.core.dao.data.batch.CatchBatchExtendDao; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; +import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchQuickFix; +import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationError; +import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidator; +import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement; +import fr.ifremer.tutti.persistence.service.BatchPersistenceService; +import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; +import fr.ifremer.tutti.persistence.service.TuttiEnumerationFile; + +@Component(value = "scientificCruiseCatchBatchValidator") +public class ScientificCruiseCatchBatchValidator implements CatchBatchValidator { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ScientificCruiseCatchBatchValidator.class); + + @Autowired + protected BatchPersistenceService batchService; + + @Autowired + protected ReferentialPersistenceService referentialService; + + @Autowired + protected CatchBatchExtendDao catchBatchDao; + + @Autowired + protected TuttiEnumerationFile enumeration; + + public ScientificCruiseCatchBatchValidator() { + } + + @Override + public boolean isEnable(fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch) { + // Apply validation only on catch batch for fishingOperation + return (catchBatch.getFishingOperation() != null); + } + + @Override + public List<CatchBatchValidationError> validate(fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch) { + List<CatchBatchValidationError> errors = Lists.newArrayList(); + validate(catchBatch.getChildBatchs(), errors, 1); + return errors; + } + + // ------------------------------------------------------------------------// + // -- Internal methods --// + // ------------------------------------------------------------------------// + + protected void validate(Collection<Batch> batchs, List<CatchBatchValidationError> errors, int treeLevel) { + + // Vrac + SortingBatch vracBatch = catchBatchDao.getSortingBatch(batchs, + "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_VRAC_ID); + if (vracBatch == null) { + addError(errors, "tutti.persistence.batch.validation.vracNotFound", null); + } else { + // Vrac > Species + SortingBatch speciesBatch = catchBatchDao.getSortingBatch(vracBatch.getChildBatchs(), + "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, + enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + if (speciesBatch == null) { + addError(errors, "tutti.persistence.batch.validation.vracSpeciesNotFound", null); + } else { + // Vrac > Species > Inert + SortingBatch inertBatch = catchBatchDao.getSortingBatch(speciesBatch.getChildBatchs(), + "referenceTaxonId", enumeration.REFERENCE_TAXON_ID_INERT); + if (inertBatch == null) { + addWarning(errors, "tutti.persistence.batch.validation.vracSpeciesInertNotFound"); + } + + // Vrac > Species > Alive no itemized + SortingBatch livingNotItemizedBatch = catchBatchDao.getSortingBatch(speciesBatch.getChildBatchs(), + "referenceTaxonId", enumeration.REFERENCE_TAXON_ID_LIFE); + if (livingNotItemizedBatch == null) { + addWarning(errors, "tutti.persistence.batch.validation.vracSpeciesLifeNotFound"); + } + } + + // TODO : Benthos, Plancton... + } + + // Hors Vrac + SortingBatch horsVracBatch = catchBatchDao.getSortingBatch(batchs, + "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, + enumeration.QUALITATIVE_HORS_VRAC_ID); + if (horsVracBatch == null) { + addWarning(errors, "tutti.persistence.batch.validation.horsVracSpeciesNotFound"); + } else { + // Hors Vrac > Species + SortingBatch speciesBatch = catchBatchDao.getSortingBatch(horsVracBatch.getChildBatchs(), + "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, + enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + if (speciesBatch == null) { + addWarning(errors, "tutti.persistence.batch.validation.horsVracSpeciesNotFound"); + } + + // TODO : Benthos, Plancton... + } + + // Unsorted + SortingBatch unsortedBatch = catchBatchDao.getSortingBatch(batchs, + "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, + enumeration.QUALITATIVE_UNSORTED_ID); + if (unsortedBatch == null) { + addWarning(errors, "tutti.persistence.batch.validation.unsortedNotFound"); + } + + // May be, the tree is an old structure + if (vracBatch == null && horsVracBatch == null && unsortedBatch == null) { + boolean allBatchHasSpecies = true; + boolean allBatchHasVrac = true; + boolean someBatchHasSortingMeasurement = false; + for (Iterator<Batch> iterator = batchs.iterator(); iterator.hasNext();) { + SortingBatch batch = (SortingBatch) iterator.next(); + if (allBatchHasSpecies && batch.getReferenceTaxon() == null) { + allBatchHasSpecies = false; + break; + } + if (allBatchHasVrac && batch.getSortingMeasurements() != null) { + if (batch.getSortingMeasurements().size() > 1) { + allBatchHasVrac = false; + someBatchHasSortingMeasurement = true; + } + else if (batch.getSortingMeasurements().size() == 1) { + someBatchHasSortingMeasurement = true; + SortingMeasurement sm = batch.getSortingMeasurements().iterator().next(); + if (enumeration.PMFM_ID_SORTED_UNSORTED.equals(sm.getPmfm().getId()) == false + || sm.getQualitativeValue() == null + || enumeration.QUALITATIVE_VRAC_ID.equals(sm.getQualitativeValue().getId()) == false) { + allBatchHasVrac = false; + } + } + } + } + if (allBatchHasSpecies && !someBatchHasSortingMeasurement) { + errors.clear(); + addError(errors, "tutti.persistence.batch.validation.onlySpeciesBatchStructure", new CatchBatchQuickFix() { + @Override + public CatchBatch repair(CatchBatch catchBatch) { + return ScientificCruiseCatchBatchValidator.this.repairHistoricalData(catchBatch, false); + } + }); + } + else if (allBatchHasSpecies && someBatchHasSortingMeasurement && allBatchHasVrac) { + errors.clear(); + addError(errors, "tutti.persistence.batch.validation.onlySpeciesBatchStructure", new CatchBatchQuickFix() { + @Override + public CatchBatch repair(CatchBatch catchBatch) { + return ScientificCruiseCatchBatchValidator.this.repairHistoricalData(catchBatch, true); + } + }); + } + } + } + + /** + * Repair tree batch, when only species have been found under the cacth batch. + * This append typically with CGFS cruise. + * @param catchBatch + * @return + */ + protected CatchBatch repairHistoricalData(CatchBatch catchBatch, boolean batchHasVracSortingMeasurement) { + Preconditions.checkNotNull(catchBatch); + Preconditions.checkNotNull(catchBatch.getId()); + Preconditions.checkNotNull(catchBatch.getFishingOperation()); + Preconditions.checkNotNull(catchBatch.getFishingOperation().getId()); + + // Copy catch batch children + Collection<Batch> speciesBatchChilds = Sets.newHashSet(); + speciesBatchChilds.addAll(catchBatch.getChildBatchs()); + catchBatch.setChildBatchs(new HashSet<Batch>()); + + // Clean catch batch + batchService.cleanEntity(catchBatch, true); + + SortingBatch speciesBatch = catchBatchDao.getSortingBatch(catchBatch.getChildBatchs(), + "pmfmId", enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_VRAC_ID, + "pmfmId", enumeration.PMFM_ID_SORTING_TYPE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + if (speciesBatch == null) { + throw new DataIntegrityViolationException("Invalid batch tree format. Could not retrieve 'Vrac>Species' batch."); + } + + // For all species batch : set the batch 'Vrac>Species' as new parent + for (Iterator<Batch> iterator = speciesBatchChilds.iterator(); iterator.hasNext();) { + SortingBatch batch = (SortingBatch) iterator.next(); + batch.setParentBatch(speciesBatch); + + if (batchHasVracSortingMeasurement) { + // Remove redundant 'Vrac' sorting measurement + SortingMeasurement sm = catchBatchDao.getSortingMeasurement(batch, enumeration.PMFM_ID_SORTED_UNSORTED, null, false); + batch.getSortingMeasurements().remove(sm); + } + + batch.setExhaustiveInventory(Boolean.TRUE); + + // Add an offset into the rank order, because of special batchs 'Biota' (=live) and 'Inert' + short rankOrder = (short)(batch.getRankOrder().shortValue() + 2); + batch.setRankOrder(rankOrder); + + // Reset comments if set to "taxon" + if (batch.getComments() != null && "taxon".equals(batch.getComments())) { + batch.setComments(null); + } + + speciesBatch.getChildBatchs().add(batch); + } + + // Save mofidifications : + catchBatchDao.update(catchBatch); + + return catchBatch; + } + + protected void addError(List<CatchBatchValidationError> errors, String messageKey, CatchBatchQuickFix quickFix) { + CatchBatchValidationError error = new CatchBatchValidationError( + messageKey, + _(messageKey), + CatchBatchValidationError.GRAVITY_ERROR); + error.setQuickFixes(Lists.newArrayList(quickFix)); + errors.add(error); + } + + protected void addWarning(List<CatchBatchValidationError> errors, String messageKey) { + CatchBatchValidationError error = new CatchBatchValidationError( + messageKey, + _(messageKey), + CatchBatchValidationError.GRAVITY_WARNING); + errors.add(error); + } + +} Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/batch/ScientificCruiseCatchBatchValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/batch/CatchBatchValidatorReadTest.java =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/batch/CatchBatchValidatorReadTest.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/batch/CatchBatchValidatorReadTest.java 2013-02-25 20:44:07 UTC (rev 476) @@ -1,121 +1,121 @@ -package fr.ifremer.tutti.persistence.service.batch; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Collection; -import java.util.List; - -import org.jmock.Expectations; -import org.jmock.Mockery; -import org.jmock.api.Invocation; -import org.jmock.integration.junit4.JUnit4Mockery; -import org.jmock.lib.action.CustomAction; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import fr.ifremer.adagio.core.dao.data.batch.CatchBatchExtendDao; -import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationException; -import fr.ifremer.adagio.core.service.ServiceLocator; -import fr.ifremer.tutti.persistence.DatabaseResource; -import fr.ifremer.tutti.persistence.entities.data.CatchBatch; -import fr.ifremer.tutti.persistence.entities.data.FishingOperation; -import fr.ifremer.tutti.persistence.service.BatchPersistenceService; -import fr.ifremer.tutti.persistence.service.CatchBatchPersistenceService; -import fr.ifremer.tutti.persistence.service.CruisePersistenceService; -import fr.ifremer.tutti.persistence.service.FishingOperationPersistenceService; -import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; -import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; - -public class CatchBatchValidatorReadTest { - - @ClassRule - public static final DatabaseResource dbResource = DatabaseResource.writeDb(); - - protected BatchPersistenceService service; - - protected CruisePersistenceService cruiseService; - - protected FishingOperationPersistenceService fishingOperationService; - - protected CatchBatchPersistenceService catchBatchService; - - protected ReferentialPersistenceService referentialService; - - Mockery context ; - - CatchBatchExtendDao catchBatchExtendDaoMock; - - String fishingOperationId = null; - - CatchBatchExtendDao catchBatchDao; - - @Before - public void setUp() throws Exception { - context = new JUnit4Mockery(); - catchBatchExtendDaoMock = context.mock(CatchBatchExtendDao.class); - catchBatchDao=ServiceLocator.instance().getService("catchBatchDao", CatchBatchExtendDao.class); - - service = TuttiPersistenceServiceLocator.getBatchPersistenceService(); - cruiseService = TuttiPersistenceServiceLocator.getCruisePersistenceService(); - fishingOperationService = TuttiPersistenceServiceLocator.getFishingOperationPersistenceService(); - catchBatchService = TuttiPersistenceServiceLocator.getCatchBatchPersistenceService(); - referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); - - List<FishingOperation> fishingOperations = fishingOperationService.getAllFishingOperation(dbResource.getFixtures().cruiseId()); - assertNotNull(fishingOperations); - assertTrue(fishingOperations.size() > 0); - fishingOperationId = fishingOperations.get(0).getId(); - } - - @Test - @Ignore - public void getInvalidCatchBatch() { - - // Full load operation - try { - CatchBatch catchBatch = service.getCatchBatchFromFishingOperation(fishingOperationId); - Assert.fail("Historical batch tree must not be valid"); - } catch (CatchBatchValidationException e) { - assertNotNull(e); - } - } - - @Test - @Ignore - public void getInvalidCatchBatchButTryRepair() throws CatchBatchValidationException { - - // Replace catchBatchDao with a mock : - //service.setCatchBatchDao(catchBatchExtendDaoMock); - - context.checking(new Expectations() {{ - // Assert update() is call once - //oneOf (catchBatchExtendDaoMock).update(with(any(fr.ifremer.adagio.core.dao.data.batch.CatchBatch.class))); - - // Delegate other methods to the real DAO - allowing(catchBatchExtendDaoMock); - will(new CustomAction("call delegated catchBatchDao") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - return invocation.applyTo(catchBatchDao); - } - }); - }}); - - CatchBatch catchBatch = null; - try { - catchBatch = service.getCatchBatchFromFishingOperation(fishingOperationId, true/*tryToRepair*/); - assertNotNull(catchBatch); - } catch (CatchBatchValidationException e) { - Assert.fail("Historical batch tree must have been repaired"); - } - context.assertIsSatisfied(); - - // Restore original dao - //service.setCatchBatchDao(catchBatchDao); - } -} +package fr.ifremer.tutti.persistence.service.batch; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.List; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.jmock.api.Invocation; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.jmock.lib.action.CustomAction; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import fr.ifremer.adagio.core.dao.data.batch.CatchBatchExtendDao; +import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationException; +import fr.ifremer.adagio.core.service.ServiceLocator; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.service.BatchPersistenceService; +import fr.ifremer.tutti.persistence.service.CatchBatchPersistenceService; +import fr.ifremer.tutti.persistence.service.CruisePersistenceService; +import fr.ifremer.tutti.persistence.service.FishingOperationPersistenceService; +import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; + +public class CatchBatchValidatorReadTest { + + @ClassRule + public static final DatabaseResource dbResource = DatabaseResource.writeDb(); + + protected BatchPersistenceService service; + + protected CruisePersistenceService cruiseService; + + protected FishingOperationPersistenceService fishingOperationService; + + protected CatchBatchPersistenceService catchBatchService; + + protected ReferentialPersistenceService referentialService; + + Mockery context ; + + CatchBatchExtendDao catchBatchExtendDaoMock; + + String fishingOperationId = null; + + CatchBatchExtendDao catchBatchDao; + + @Before + public void setUp() throws Exception { + context = new JUnit4Mockery(); + catchBatchExtendDaoMock = context.mock(CatchBatchExtendDao.class); + catchBatchDao=ServiceLocator.instance().getService("catchBatchDao", CatchBatchExtendDao.class); + + service = TuttiPersistenceServiceLocator.getBatchPersistenceService(); + cruiseService = TuttiPersistenceServiceLocator.getCruisePersistenceService(); + fishingOperationService = TuttiPersistenceServiceLocator.getFishingOperationPersistenceService(); + catchBatchService = TuttiPersistenceServiceLocator.getCatchBatchPersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + + List<FishingOperation> fishingOperations = fishingOperationService.getAllFishingOperation(dbResource.getFixtures().cruiseId()); + assertNotNull(fishingOperations); + assertTrue(fishingOperations.size() > 0); + fishingOperationId = fishingOperations.get(0).getId(); + } + + @Test + @Ignore + public void getInvalidCatchBatch() { + + // Full load operation + try { + CatchBatch catchBatch = service.getCatchBatchFromFishingOperation(fishingOperationId); + Assert.fail("Historical batch tree must not be valid"); + } catch (CatchBatchValidationException e) { + assertNotNull(e); + } + } + + @Test + @Ignore + public void getInvalidCatchBatchButTryRepair() throws CatchBatchValidationException { + + // Replace catchBatchDao with a mock : + //service.setCatchBatchDao(catchBatchExtendDaoMock); + + context.checking(new Expectations() {{ + // Assert update() is call once + //oneOf (catchBatchExtendDaoMock).update(with(any(fr.ifremer.adagio.core.dao.data.batch.CatchBatch.class))); + + // Delegate other methods to the real DAO + allowing(catchBatchExtendDaoMock); + will(new CustomAction("call delegated catchBatchDao") { + @Override + public Object invoke(Invocation invocation) throws Throwable { + return invocation.applyTo(catchBatchDao); + } + }); + }}); + + CatchBatch catchBatch = null; + try { + catchBatch = service.getCatchBatchFromFishingOperation(fishingOperationId, true/*tryToRepair*/); + assertNotNull(catchBatch); + } catch (CatchBatchValidationException e) { + Assert.fail("Historical batch tree must have been repaired"); + } + context.assertIsSatisfied(); + + // Restore original dao + //service.setCatchBatchDao(catchBatchDao); + } +} Property changes on: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/batch/CatchBatchValidatorReadTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java 2013-02-25 20:44:07 UTC (rev 476) @@ -85,6 +85,11 @@ return "Tutti Persistence Service"; } + @Override + public void clearAllCaches() { + driver.clearAllCaches(); + } + public boolean isDbLoaded() { return !(driver instanceof TuttiPersistenceNoDbImpl); } Modified: trunk/tutti-ui-swing/pom.xml =================================================================== --- trunk/tutti-ui-swing/pom.xml 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-ui-swing/pom.xml 2013-02-25 20:44:07 UTC (rev 476) @@ -287,6 +287,11 @@ <classifier>tests</classifier> </dependency> + <dependency> + <groupId>org.apache.struts.xwork</groupId> + <artifactId>xwork-core</artifactId> + </dependency> + <!-- librairie Jaxx --> <dependency> <groupId>org.nuiton.jaxx</groupId> Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java 2013-02-25 20:44:07 UTC (rev 476) @@ -29,6 +29,7 @@ import com.google.common.collect.Maps; import fr.ifremer.tutti.persistence.ProgressionModel; import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeResult; +import fr.ifremer.tutti.service.PersistenceService; import fr.ifremer.tutti.service.TuttiTechnicalException; import fr.ifremer.tutti.service.referential.TuttiReferentialSynchronizeService; import fr.ifremer.tutti.ui.swing.util.action.TuttiActionUI; @@ -103,11 +104,7 @@ if (types.contains(UpdateType.DB)) { ApplicationUpdater.ApplicationInfo info = getInfo(UpdateType.DB, result); - if (info == null) { - dbUpdated = false; - } else { - dbUpdated = true; - } + dbUpdated = info != null; } return result; } @@ -322,5 +319,28 @@ } service.synchronize(dbDirectory, result); + + if (!result.isSuccess()) { + throw new TuttiTechnicalException("Could not synchro db", result.getError()); + } + + // reset cache + if (log.isInfoEnabled()) { + log.info("Reset all caches."); + } + PersistenceService persistence = context.getService(PersistenceService.class); + persistence.clearAllCaches(); + + // replace the version.appup file content + File target = context.getConfig().getServiceConfig().getPersistenceConfig().getDbDirectory(); + File versionFile = new File(target, ApplicationUpdater.VERSION_FILE); + if (log.isInfoEnabled()) { + log.info("Replace content of file " + versionFile + " with " + info.newVersion); + } + try { + FileUtils.writeStringToFile(versionFile, info.newVersion); + } catch (IOException e) { + throw new TuttiTechnicalException("Could not write back new db version to file " + versionFile); + } } } Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/SelectOtherSpeciesAction.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/SelectOtherSpeciesAction.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/SelectOtherSpeciesAction.java 2013-02-25 20:44:07 UTC (rev 476) @@ -1,6 +1,30 @@ package fr.ifremer.tutti.ui.swing.content.protocol; +/* + * #%L + * Tutti :: UI + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 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.collect.Lists; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.ui.swing.AbstractTuttiAction; Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/TuttiCollectionUniqueKeyValidator.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/TuttiCollectionUniqueKeyValidator.java 2013-02-25 19:43:58 UTC (rev 475) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/TuttiCollectionUniqueKeyValidator.java 2013-02-25 20:44:07 UTC (rev 476) @@ -1,5 +1,29 @@ package fr.ifremer.tutti.ui.swing.util; +/* + * #%L + * Tutti :: UI + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 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.opensymphony.xwork2.validator.ValidationException; import org.nuiton.validator.xwork2.field.CollectionUniqueKeyValidator; Property changes on: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/util/TuttiCollectionUniqueKeyValidator.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL