This is an automated email from the git hooks/post-receive script. New commit to branch feature/revue_algorithme in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 2dad5f37f58930d5fb512d9a4325c2b5304d647a Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Apr 19 10:50:16 2016 +0200 Revue de comment interroger le cache --- ...cesSamplingAlgorithmEntryNotFoundException.java | 17 + .../service/sampling/CruiseSamplingCache.java | 576 ++++++++++----------- .../sampling/CruiseSamplingInternalCache.java | 147 ++---- .../IndividualObservationSamplingContext.java | 148 ++++++ .../IndividualObservationSamplingStatus.java | 126 +++++ ...lObservationSamplingStatusExceptionSupport.java | 29 ++ .../tutti/service/sampling/SamplingEvent.java | 68 +-- .../tutti/service/sampling/SamplingListener.java | 1 - ...NotDefinedOnIndividualObservationException.java | 17 + .../ZoneNotDefinedOnFishingOperationException.java | 17 + 10 files changed, 691 insertions(+), 455 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java new file mode 100644 index 0000000..b099a83 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand l'algorithme de prélèvement de pièces calcifiés n'est pas trouvé pour une observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class CalcifiedPiecesSamplingAlgorithmEntryNotFoundException extends IndividualObservationSamplingStatusExceptionSupport { + + public CalcifiedPiecesSamplingAlgorithmEntryNotFoundException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java index 663a33f..61507f6 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java @@ -64,15 +64,15 @@ public class CruiseSamplingCache implements CruiseCacheAble { /** * Le cache des échantillons au niveau de la campagne. */ - private final CruiseSamplingInternalCache totalCruiseCache = new CruiseSamplingInternalCache(); + private final CruiseSamplingInternalCache cruiseCache = new CruiseSamplingInternalCache(); /** * Le cache des échantillons au niveau de chaque zone. */ private final CruiseSamplingInternalCache zoneCache = new CruiseSamplingInternalCache(); /** - * Le cache des échantillons au niveau de chaque opération. + * Le cache des échantillons au niveau de chaque opération de pêche. */ - private final CruiseSamplingInternalCache operationCache = new CruiseSamplingInternalCache(); + private final CruiseSamplingInternalCache fishingOperationCache = new CruiseSamplingInternalCache(); /** * Le dictionnaire des identifiants de strates ou sous-strates pour chaque zone. */ @@ -146,12 +146,20 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, on n'enregistre rien ici. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { - - Zone optionalZone = tryFindZone(fishingOperation).orElse(null); int fishingOperationId = fishingOperation.getIdAsInt(); for (IndividualObservationBatch individualObservationBatch : individualObservations) { @@ -178,14 +186,23 @@ public class CruiseSamplingCache implements CruiseCacheAble { CaracteristicQualitativeValue gender = individualObservationBatch.getCaracteristics().getQualitativeValue(sexCaracteristic); - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); +// CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + zone, + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStepInMm, + maturity, + gender); - addIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + addIndividualObservation(individualObservationSamplingContext); String samplingCode = individualObservationBatch.getSamplingCode(); if (samplingCode != null) { - addSampling(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + addSampling(individualObservationSamplingContext); } @@ -205,11 +222,20 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, rien à supprimer alors. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { - Zone optionalZone = tryFindZone(fishingOperation).orElse(null); int fishingOperationId = fishingOperation.getIdAsInt(); for (IndividualObservationBatch individualObservationBatch : individualObservations) { @@ -219,7 +245,7 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // pas dans l'algorithme, one ne tient pas compte de cette observation + // pas dans l'algorithme, on ne tient pas compte de cette observation continue; } @@ -228,21 +254,32 @@ public class CruiseSamplingCache implements CruiseCacheAble { Boolean maturity = getMaturity(individualObservationBatch); + Objects.requireNonNull(individualObservationBatch.getSize()); float lengthStep = individualObservationBatch.getSize(); int lengthStepInMm = Numbers.convertToMm(lengthStep, individualObservationBatch.getLengthStepCaracteristic().getUnit()); CaracteristicQualitativeValue gender = individualObservationBatch.getCaracteristics().getQualitativeValue(sexCaracteristic); - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); +// CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + zone, + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStepInMm, + maturity, + gender); String samplingCode = individualObservationBatch.getSamplingCode(); if (samplingCode != null) { - removeSampling(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + removeSampling(individualObservationSamplingContext); } - removeIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + + removeIndividualObservation(individualObservationSamplingContext); } @@ -260,6 +297,16 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, rien à supprimer alors. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { @@ -271,27 +318,23 @@ public class CruiseSamplingCache implements CruiseCacheAble { } // suppression de toutes les entrées du cache des opérations (et récupération des clefs) - Set<String> removedKeys = operationCache.removeAllWhereKeyStartingWith(fishingOperationId); + Set<String> removedKeys = fishingOperationCache.removeAllWhereKeyStartingWith(fishingOperationId); if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from operationCache: " + operationCache.size()); + log.info("Fishing operation: " + fishingOperation + " removed from fishingOperationCache: " + fishingOperationCache.size()); } - removedKeys.forEach(totalCruiseCache::decrementObservationNb); + removedKeys.forEach(cruiseCache::removeOneIndividualObservation); if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from totalCruiseCache: " + totalCruiseCache.size()); + log.info("Fishing operation: " + fishingOperation + " removed from cruiseCache: " + cruiseCache.size()); } - Optional<Zone> optionalZone = tryFindZone(fishingOperation); + String zoneId = zone.getId(); + removedKeys.forEach(key -> zoneCache.removeOneIndividualObservation(CruiseSamplingInternalCache.addPrefixKey(zoneId, key))); - if (optionalZone.isPresent()) { - String zoneId = optionalZone.get().getId(); - removedKeys.forEach(key -> zoneCache.decrementObservationNbIfExist(CruiseSamplingInternalCache.addPrefixKey(zoneId, key))); - - if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from zoneCache: " + zoneCache.size()); - } + if (log.isInfoEnabled()) { + log.info("Fishing operation: " + fishingOperation + " removed from zoneCache: " + zoneCache.size()); } if (log.isInfoEnabled()) { @@ -312,9 +355,9 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (log.isInfoEnabled()) { log.info("Closing cruise sampling cache."); } - totalCruiseCache.close(); + cruiseCache.close(); zoneCache.close(); - operationCache.close(); + fishingOperationCache.close(); locationIdsPerZone.clear(); cpsDefinitionsBySpecies.clear(); maturityCaracteristicBySpecies.clear(); @@ -329,63 +372,63 @@ public class CruiseSamplingCache implements CruiseCacheAble { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("totalCruiseCache", totalCruiseCache.size()) + .add("cruiseCache", cruiseCache.size()) .add("zoneCache", zoneCache.size()) - .add("operationCache", operationCache.size()) + .add("fishingOperationCache", fishingOperationCache.size()) .toString(); } - public CalcifiedPiecesSamplingStatus getStatus(IndividualObservationBatch individualObservationBatch, - Integer lengthStep, - CaracteristicQualitativeValue gender, - Boolean maturity) { - - Objects.requireNonNull(individualObservationBatch); + public IndividualObservationSamplingStatus getIndividualObservationSamplingStatus(FishingOperation fishingOperation, + IndividualObservationBatch individualObservationBatch, + Integer lengthStep, + CaracteristicQualitativeValue gender, + CaracteristicQualitativeValue maturity) throws SizeNotDefinedOnIndividualObservationException, ZoneNotDefinedOnFishingOperationException, CalcifiedPiecesSamplingAlgorithmEntryNotFoundException { - FishingOperation fishingOperation = individualObservationBatch.getFishingOperation(); Objects.requireNonNull(fishingOperation); + Objects.requireNonNull(individualObservationBatch); Species species = individualObservationBatch.getSpecies(); Objects.requireNonNull(species); if (lengthStep == null) { - // pas de classe de taille définie, on ne peut rien calculer - // on considère que l'observation individuelle ne rentre pas dans l'algorithme - - throw new RuntimeException(""); - + throw new SizeNotDefinedOnIndividualObservationException(individualObservationBatch); } Optional<Zone> optionalZone = tryFindZone(fishingOperation); if (!optionalZone.isPresent()) { - throw new IllegalStateException("Can't find zone for a matching individual observation: " + individualObservationBatch); + + throw new ZoneNotDefinedOnFishingOperationException(individualObservationBatch); } + Boolean maturityAsBoolean = getMaturity(individualObservationBatch, maturity); + Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = - tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); + tryToFindCalcifiedPiecesSamplingDefinition(species, maturityAsBoolean, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // ne rentre pas dans l'algorithme - throw new RuntimeException(""); - + throw new CalcifiedPiecesSamplingAlgorithmEntryNotFoundException(individualObservationBatch); } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext context = createContext(fishingOperation.getIdAsInt(), + individualObservationBatch.getSpecies(), + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturityAsBoolean, + gender); + String cruiseSamplingKey = context.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.getSamplingData(cruiseSamplingKey); - Zone zone = optionalZone.get(); - int totalSamplingInCruise = 0; - int totalSamplingInFishingOperation = 0; - int totalSamplingInZone = 0; + String zoneSamplingKey = context.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.getSamplingData(zoneSamplingKey); - return new CalcifiedPiecesSamplingStatus(individualObservationBatch, - calcifiedPiecesSamplingDefinition, - zone, - totalSamplingInCruise, - totalSamplingInFishingOperation, - totalSamplingInZone); + String fishingOperationSamplingKey = context.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.getSamplingData(fishingOperationSamplingKey); + + return new IndividualObservationSamplingStatus(context, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); } @@ -407,20 +450,36 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(species); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not add individual observation in cache, fishing operation has no matching zone."); + } + return; + } + Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // pas dans l'algorithme, one ne tient pas compte de cette observation + if (log.isInfoEnabled()) { + log.info("Do not add individual observation in cache, no definition matched."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - Optional<Zone> optionalZone = tryFindZone(fishingOperation); - - addIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + addIndividualObservation(individualObservationSamplingContext); } @@ -443,17 +502,35 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not remove individual observation from cache, fishing operation has no matching zone."); + } + return; + } Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not remove individual observation from cache, no definition matched."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - removeIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + removeIndividualObservation(individualObservationSamplingContext); } @@ -476,6 +553,13 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not record sampling in cache, fishing operation has no matching zone."); + } + return; + } Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); @@ -483,14 +567,21 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { if (log.isInfoEnabled()) { - log.info("Do not record sampling code in cache, definition not matched."); + log.info("Do not record sampling in cache, no definition matched."); } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - addSampling(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + addSampling(individualObservationSamplingContext); } @@ -513,72 +604,34 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { - Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); - - if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { + if (log.isInfoEnabled()) { + log.info("Do not remove sampling from cache, fishing operation has no matching zone."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); - - removeSampling(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); - - } - - public Optional<SamplingEvent> getEventForSummary(FishingOperation fishingOperation, - Species species, - Boolean maturity, - CaracteristicQualitativeValue gender, - int lengthStep) { - - Objects.requireNonNull(fishingOperation); - Objects.requireNonNull(species); - Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); - SamplingEvent event = null; - if (optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); - - if (log.isInfoEnabled()) { - log.info("Found matching sampling definition: " + calcifiedPiecesSamplingDefinition); - } - - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } - - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); - - int totalValue = totalCruiseCache.getObservationNb(samplingKey); - int totalSamplingNb = totalCruiseCache.getSamplingNb(samplingKey); - - int zoneValue = 0; - int zoneSamplingNb = 0; - - Optional<Zone> optionalZone = tryFindZone(fishingOperation); - if (optionalZone.isPresent()) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(optionalZone.get().getId(), samplingKey); - zoneValue = zoneCache.getObservationNb(zoneKey); - zoneSamplingNb = zoneCache.getSamplingNb(zoneKey); - } - - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperation.getIdAsInt(), samplingKey); - - int operationValue = operationCache.getObservationNb(operationKey); - int operationSamplingNb = operationCache.getSamplingNb(operationKey); + if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { if (log.isInfoEnabled()) { - log.info("add Individual Observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); + log.info("Do not remove sampling from cache, no definition matched."); } - - event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, optionalZone.orElse(null), totalSamplingNb, zoneSamplingNb, operationSamplingNb); - + return; } - return Optional.ofNullable(event); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); + + removeSampling(individualObservationSamplingContext); } @@ -607,7 +660,18 @@ public class CruiseSamplingCache implements CruiseCacheAble { listeners.remove(SamplingListener.class, listener); } - private Optional<Zone> tryFindZone(FishingOperation operation) { + public List<CacheExtractedKey> getSamplingNumbers(Map<String, Species> speciesById) { + List<CacheExtractedKey> result = cruiseCache.getSamplingNumbers(speciesById, sexQualitativeValues); + result.forEach(key -> { + Optional<CalcifiedPiecesSamplingDefinition> cpsDef = tryToFindCalcifiedPiecesSamplingDefinition(key.getSpecies(), key.getMaturity(), key.getLengthStep(), key.getSex()); + if (cpsDef.isPresent()) { + key.setMaxByLengthStep(cpsDef.get().getMaxByLenghtStep()); + } + }); + return result; + } + + public Optional<Zone> tryFindZone(FishingOperation operation) { Optional<Zone> result; if (operation.getSubStrata() != null) { result = tryFindZone(operation.getSubStrata()); @@ -619,24 +683,17 @@ public class CruiseSamplingCache implements CruiseCacheAble { return result; } - private void fireSamplingNeeded(SamplingEvent event) { - - SamplingListener[] samplingListeners = listeners.getListeners(SamplingListener.class); - if (samplingListeners.length > 0) { - - for (SamplingListener listener : samplingListeners) { - listener.samplingNeeded(event); - } - } + public boolean isSpeciesDefined(Species species) { + return cpsDefinitionsBySpecies.containsKey(species.getReferenceTaxonId()); } - private void fireSummaryUpdated(SamplingEvent event) { + private void fireSamplingNeeded(SamplingEvent event) { SamplingListener[] samplingListeners = listeners.getListeners(SamplingListener.class); if (samplingListeners.length > 0) { for (SamplingListener listener : samplingListeners) { - listener.summaryUpdated(event); + listener.samplingNeeded(event); } } } @@ -664,81 +721,65 @@ public class CruiseSamplingCache implements CruiseCacheAble { return maturity; } - public List<CacheExtractedKey> getSamplingNumbers(Map<String, Species> speciesById) { - List<CacheExtractedKey> result = totalCruiseCache.getSamplingNumbers(speciesById, sexQualitativeValues); - result.forEach(key -> { - Optional<CalcifiedPiecesSamplingDefinition> cpsDef = tryToFindCalcifiedPiecesSamplingDefinition(key.getSpecies(), key.getMaturity(), key.getLengthStep(), key.getSex()); - if (cpsDef.isPresent()) { - key.setMaxByLengthStep(cpsDef.get().getMaxByLenghtStep()); + private Boolean getMaturity(IndividualObservationBatch individualObservationBatch, CaracteristicQualitativeValue qualitativeValue) { + Boolean maturity = null; + Caracteristic maturityCaracteristic = maturityCaracteristicBySpecies.get(individualObservationBatch.getSpecies().getReferenceTaxonId()); + // if a maturity caracteristic is defined in the protocol for this species + if (maturityCaracteristic != null) { + // it the maturity is set + if (qualitativeValue != null) { + maturity = matureStatesByMaturityCracteristic.containsEntry(maturityCaracteristic.getId(), qualitativeValue.getId()); } - }); - return result; - } - - private void addIndividualObservation(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; } + return maturity; + } - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); - - if (isLoading()) { + private String createCruiseSamplingKey(Species species, + CaracteristicQualitativeValue gender, + Boolean maturity, + int lengthStep) { + return CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + } - int totalValue = totalCruiseCache.incrementObservationNb(samplingKey); + private String createZoneSamplingKey(String cruiseSamplingKey, Zone zone) { + return CruiseSamplingInternalCache.addPrefixKey(zone.getId(), cruiseSamplingKey); + } - int zoneValue = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.incrementObservationNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + private String createFishingOperationSamplingKey(String cruiseSamplingKey, int fishingOperationId) { + return CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, cruiseSamplingKey); + } - int operationValue = operationCache.incrementObservationNb(operationKey); + private void addIndividualObservation(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (log.isInfoEnabled()) { - log.info("add individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); - } + Objects.requireNonNull(individualObservationSamplingContext); - } else { + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.addOneIndividualObservation(cruiseSamplingKey); - int totalValue = totalCruiseCache.incrementObservationNb(samplingKey); - int totalSamplingNb = totalCruiseCache.getSamplingNb(samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.addOneIndividualObservation(zoneSamplingKey); - int zoneValue = 0; - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.incrementObservationNb(zoneKey); - zoneSamplingNb = zoneCache.getSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.addOneIndividualObservation(fishingOperationSamplingKey); - int operationValue = operationCache.incrementObservationNb(operationKey); - int operationSamplingNb = operationCache.getSamplingNb(operationKey); + if (log.isInfoEnabled()) { + log.info("add individual observation " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); + } - if (log.isInfoEnabled()) { - log.info("add individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); - } + if (!isLoading()) { - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); + int samplingInterval = individualObservationSamplingContext.getCalcifiedPiecesSamplingDefinition().getSamplingInterval(); + int cruiseIndividualObservationCount = cruiseSamplingData.getIndividualObservationCount(); + if (cruiseIndividualObservationCount == 1 || samplingInterval == 1 || cruiseIndividualObservationCount % samplingInterval == 1) { - int samplingInterval = calcifiedPiecesSamplingDefinition.getSamplingInterval(); - if (totalValue == 1 || samplingInterval == 1 || totalValue % samplingInterval == 1) { + IndividualObservationSamplingStatus status = new IndividualObservationSamplingStatus(individualObservationSamplingContext, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); + SamplingEvent event = new SamplingEvent(this, status); if (log.isInfoEnabled()) { log.info("-> needs sampling"); } fireSamplingNeeded(event); } - fireSummaryUpdated(event); - } } @@ -746,140 +787,86 @@ public class CruiseSamplingCache implements CruiseCacheAble { /** * Suppression d'un échantillon du cache. * - * @param calcifiedPiecesSamplingDefinition la définition de l'alrithme à utiliser - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) + * @param individualObservationSamplingContext le contexte de l'observation individuelle */ - private void removeIndividualObservation(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void removeIndividualObservation(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } + Objects.requireNonNull(individualObservationSamplingContext); - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.removeOneIndividualObservation(cruiseSamplingKey); - int totalValue = totalCruiseCache.decrementObservationNb(samplingKey); - int zoneValue = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.decrementObservationNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.removeOneIndividualObservation(zoneSamplingKey); - int operationValue = operationCache.decrementObservationNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.removeOneIndividualObservation(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("remove individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); + log.info("remove individual observation " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } } - /** - * Ajout d'un prélèvement dans le cache. - * - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) - */ - private void addSampling(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void addSampling(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + Objects.requireNonNull(individualObservationSamplingContext); - int totalSamplingNb = totalCruiseCache.incrementSamplingNb(samplingKey); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.addOneSampling(cruiseSamplingKey); - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneSamplingNb = zoneCache.incrementSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.addOneSampling(zoneSamplingKey); - int operationSamplingNb = operationCache.incrementSamplingNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.addOneSampling(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("add Sampling " + samplingKey + " => op " + operationSamplingNb + " / zone " + zoneSamplingNb + " / cruise " + totalSamplingNb); + log.info("add Sampling " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); - fireSummaryUpdated(event); - } - /** - * Suppression d'un prélèvement dans le cache. - * - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) - */ - private void removeSampling(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void removeSampling(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } + Objects.requireNonNull(individualObservationSamplingContext); - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.removeOneSampling(cruiseSamplingKey); - int totalSamplingNb = totalCruiseCache.decrementSamplingNb(samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.removeOneSampling(zoneSamplingKey); - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneSamplingNb = zoneCache.decrementSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); - - int operationSamplingNb = operationCache.decrementSamplingNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.removeOneSampling(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("remove Sampling " + samplingKey + " => op " + operationSamplingNb + " / zone " + zoneSamplingNb + " / cruise " + totalSamplingNb); + log.info("remove Sampling " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); - fireSummaryUpdated(event); + } + + private IndividualObservationSamplingContext createContext(int fishingOperationId, + Species species, + Zone zone, + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, + Integer lengthStep, + Boolean maturity, + CaracteristicQualitativeValue gender) { + + String cruiseSamplingKey = createCruiseSamplingKey(species, gender, maturity, lengthStep); + String zoneSamplingKey = createZoneSamplingKey(cruiseSamplingKey, zone); + String fishingOperationSamplingKey = createFishingOperationSamplingKey(cruiseSamplingKey, fishingOperationId); + + return new IndividualObservationSamplingContext(species, + lengthStep, + maturity, + gender, + calcifiedPiecesSamplingDefinition, + zone, + cruiseSamplingKey, + zoneSamplingKey, + fishingOperationSamplingKey); } @@ -972,5 +959,4 @@ public class CruiseSamplingCache implements CruiseCacheAble { return Optional.ofNullable(result); } - } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java index 371d836..9b896d4 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java @@ -70,77 +70,14 @@ class CruiseSamplingInternalCache implements Closeable { private final Map<String, SamplingData> data = new TreeMap<>(); - public int incrementObservationNb(String samplingKey) { + public SamplingData getSamplingData(String samplingKey) { Objects.requireNonNull(samplingKey); - SamplingData value = data.computeIfAbsent(samplingKey, s -> new SamplingData()); - int obsNb = value.incrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + obsNb); - } - return obsNb; - } - - public int decrementObservationNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int obsNb = value.decrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + obsNb); - } - return obsNb; - } - - public Integer decrementObservationNbIfExist(String samplingKey) { - Objects.requireNonNull(samplingKey); - Integer result = null; - SamplingData value = data.get(samplingKey); - if (value != null) { - result = value.decrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + value); - } - } - return result; - } - - public int getObservationNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int observationNb = value.getObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + observationNb); - } - return observationNb; + return data.get(samplingKey); } - public int incrementSamplingNb(String samplingKey) { + public SamplingData getOrCreateSamplingData(String samplingKey) { Objects.requireNonNull(samplingKey); - SamplingData value = data.computeIfAbsent(samplingKey, s -> new SamplingData()); - int samplingNb = value.incrementSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; - } - - public int decrementSamplingNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int samplingNb = value.decrementSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; - } - - public int getSamplingNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int samplingNb = value.getSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; + return data.computeIfAbsent(samplingKey, s -> new SamplingData()); } @Override @@ -229,7 +166,7 @@ class CruiseSamplingInternalCache implements Closeable { key.setLengthStep(lengthStep); } - key.setSamplingNb(samplingData.getSamplingNb()); + key.setSamplingNb(samplingData.getSamplingCount()); result.add(key); } @@ -240,54 +177,68 @@ class CruiseSamplingInternalCache implements Closeable { } - private class SamplingData { + public SamplingData addOneIndividualObservation(String key) { + SamplingData samplingData = getOrCreateSamplingData(key); + samplingData.individualObservationCount++; + return samplingData; + } - private int observationNb; - private int samplingNb; + public SamplingData removeOneIndividualObservation(String key) { + SamplingData samplingData = getSamplingData(key); - public int incrementObservationNb() { - observationNb++; - return getObservationNb(); - } + Objects.requireNonNull(samplingData, "[" + key + "] You cannot decrement a individual observation if the sampling data does not exist"); + Preconditions.checkState(samplingData.withIndividualObservation(), "[" + key + "] You cannot decrement the observation count if there is no observation"); + samplingData.individualObservationCount--; + return samplingData; + } - public int decrementObservationNb() { - Preconditions.checkState(withObservation(), "You cannot decrement the observation number if there is no observation"); - observationNb--; - return getObservationNb(); - } + public SamplingData addOneSampling(String key) { + //FIXME Normalement on ne doit pas créer ici car si on ajoute un prélèvement c'est qu'il y a déjà au préalable une observation + SamplingData samplingData = getOrCreateSamplingData(key); + samplingData.samplingCount++; + return samplingData; + } - public int getObservationNb() { - return observationNb; - } + public SamplingData removeOneSampling(String key) { + SamplingData samplingData = getSamplingData(key); + Objects.requireNonNull(samplingData, "[" + key + "] You cannot decrement a sampling count if the sampling data does not exist"); + Preconditions.checkState(samplingData.withSampling(), "[" + key + "] You cannot decrement a sampling count if there is no sampling"); + samplingData.samplingCount--; + return samplingData; + } - public int incrementSamplingNb() { - samplingNb++; - return getSamplingNb(); - } + class SamplingData { + + /** + * Nombre d'observations individuelles. + */ + private int individualObservationCount; + /** + * Nombre de prélèvements. + */ + private int samplingCount; - public int decrementSamplingNb() { - Preconditions.checkState(withSampling(), "You cannot decrement a sampling number if there is no sampling"); - samplingNb--; - return getSamplingNb(); + public int getIndividualObservationCount() { + return individualObservationCount; } public boolean withSampling() { - return samplingNb > 0; + return samplingCount > 0; } - public boolean withObservation() { - return observationNb > 0; + public boolean withIndividualObservation() { + return individualObservationCount > 0; } - public int getSamplingNb() { - return samplingNb; + public int getSamplingCount() { + return samplingCount; } @Override public String toString() { return MoreObjects.toStringHelper(SamplingData.class) - .add("observationNb", observationNb) - .add("samplingNb", samplingNb) + .add("individualObservationCount", individualObservationCount) + .add("samplingCount", samplingCount) .toString(); } } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java new file mode 100644 index 0000000..2ec4318 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java @@ -0,0 +1,148 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.util.Objects; + +/** + * Définit le context d'une observation individuelles ou d'un prélèvement, i.e toutes les caractéristiques qui + * permettent de retrouver cette observation individuelle au niveau de l'algorithme de prélèvement. + * + * L'utilisation de cet objet sous-entend que l'observation individuelle liée rentre bien dans l'algorithme. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationSamplingContext { + + /** + * L'espèce de l'observation individuelle. + */ + private final Species species; + + /** + * La classe de taille de l'observation individuelle. + */ + private final Integer lengthStep; + + /** + * Le statut de maturité. + */ + private final Boolean maturity; + + /** + * Le sexe observé. + */ + private final CaracteristicQualitativeValue gender; + + /** + * La définition de l'algorithme de prélèvement de picèes calcifiées utilisée pour cette observation. + */ + private final CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition; + + /** + * La zone où est effectuée l'observation individuelle. + */ + private final Zone zone; + + /** + * La clef pour accéder au cache des compteurs (de niveau Campagne). + */ + private final String cruiseSamplingKey; + + /** + * La clef pour accéder au cache des compteurs (de niveau Zone). + */ + private final String zoneSamplingKey; + + /** + * La clef pour accéder au cache des compteurs (de niveau Opération de pêche). + */ + private final String fishingOperationSamplingKey; + + public IndividualObservationSamplingContext(Species species, + Integer lengthStep, + Boolean maturity, + CaracteristicQualitativeValue gender, + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, + Zone zone, + String cruiseSamplingKey, + String zoneSamplingKey, + String fishingOperationSamplingKey) { + Objects.requireNonNull(species); + Objects.requireNonNull(calcifiedPiecesSamplingDefinition); + Objects.requireNonNull(zone); + Objects.requireNonNull(cruiseSamplingKey); + Objects.requireNonNull(zoneSamplingKey); + Objects.requireNonNull(fishingOperationSamplingKey); + this.species = species; + this.lengthStep = lengthStep; + this.maturity = maturity; + this.gender = gender; + this.calcifiedPiecesSamplingDefinition = calcifiedPiecesSamplingDefinition; + this.zone = zone; + this.cruiseSamplingKey = cruiseSamplingKey; + this.zoneSamplingKey = zoneSamplingKey; + this.fishingOperationSamplingKey = fishingOperationSamplingKey; + } + + public Species getSpecies() { + return species; + } + + public Integer getLengthStep() { + return lengthStep; + } + + public Boolean getMaturity() { + return maturity; + } + + public CaracteristicQualitativeValue getGender() { + return gender; + } + + public CalcifiedPiecesSamplingDefinition getCalcifiedPiecesSamplingDefinition() { + return calcifiedPiecesSamplingDefinition; + } + + public Zone getZone() { + return zone; + } + + public int getTotalSamplingRequiredInCruise() { + return calcifiedPiecesSamplingDefinition.getMaxByLenghtStep(); + } + + public int getTotalSamplingRequiredInFishingOperation() { + return calcifiedPiecesSamplingDefinition.getOperationLimitation(); + } + + public int getTotalSamplingRequiredInZone() { + return calcifiedPiecesSamplingDefinition.getZoneLimitation(); + } + + public String getCruiseSamplingKey() { + return cruiseSamplingKey; + } + + public String getZoneSamplingKey() { + return zoneSamplingKey; + } + + public String getFishingOperationSamplingKey() { + return fishingOperationSamplingKey; + } + + public boolean withGender() { + return gender!=null; + } + + public boolean withMaturity() { + return maturity!=null; + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java new file mode 100644 index 0000000..92184c6 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java @@ -0,0 +1,126 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; + +import java.util.Objects; + +/** + * Définit l'état en terme de prélèvement (de pièces calcifiées) d'une observation individuelle. + * + * L'utilisation de cet objet sous-entend que l'observation individuelle liée rentre bien dans l'algorithme. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationSamplingStatus { + + /** + * Le context d'une observation individuelle (i.e ses caractéristiques). + */ + private final IndividualObservationSamplingContext individualObservationSamplingContext; + + /** + * Le nombre d'observations individuelles similaires effectués sur la campagne. + */ + private final int individualObservationCountInCruise; + + /** + * Le nombre de prélèvements similaires effectués sur la campagne. + */ + private final int samplingCountInCruise; + + /** + * Le nombre d'observations individuelles similaires effectués sur l'opération de pêche. + */ + private final int individualObservationCountInFishingOperation; + + /** + * Le nombre de prélèvements similaires effectués sur l'opération de pêche. + */ + private final int samplingCountInFishingOperation; + + /** + * Le nombre d'observations individuelles similaires effectués sur la zone. + */ + private final int individualObservationCountInZone; + + /** + * Le nombre de prélèvements similaires effectués sur la zone. + */ + private final int samplingCountInZone; + + public IndividualObservationSamplingStatus(IndividualObservationSamplingContext individualObservationSamplingContext, + CruiseSamplingInternalCache.SamplingData cruiseSamplingData, + CruiseSamplingInternalCache.SamplingData zoneSamplingData, + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData) { + Objects.requireNonNull(individualObservationSamplingContext); + this.individualObservationSamplingContext = individualObservationSamplingContext; + this.samplingCountInCruise = cruiseSamplingData.getSamplingCount(); + this.individualObservationCountInCruise = cruiseSamplingData.getIndividualObservationCount(); + this.samplingCountInZone = zoneSamplingData.getSamplingCount(); + this.individualObservationCountInZone = zoneSamplingData.getIndividualObservationCount(); + this.samplingCountInFishingOperation = fishingOperationSamplingData.getSamplingCount(); + this.individualObservationCountInFishingOperation = fishingOperationSamplingData.getIndividualObservationCount(); + } + + public IndividualObservationSamplingContext getIndividualObservationSamplingContext() { + return individualObservationSamplingContext; + } + + public CalcifiedPiecesSamplingDefinition getCalcifiedPiecesSamplingDefinition() { + return individualObservationSamplingContext.getCalcifiedPiecesSamplingDefinition(); + } + + public int getSamplingCountInCruise() { + return samplingCountInCruise; + } + + public int getSamplingCountInFishingOperation() { + return samplingCountInFishingOperation; + } + + public int getSamplingCountInZone() { + return samplingCountInZone; + } + + public int getIndividualObservationCountInCruise() { + return individualObservationCountInCruise; + } + + public int getIndividualObservationCountInFishingOperation() { + return individualObservationCountInFishingOperation; + } + + public int getIndividualObservationCountInZone() { + return individualObservationCountInZone; + } + + public int getTotalSamplingRequiredInCruise() { + return getCalcifiedPiecesSamplingDefinition().getMaxByLenghtStep(); + } + + public int getTotalSamplingRequiredInFishingOperation() { + return getCalcifiedPiecesSamplingDefinition().getOperationLimitation(); + } + + public int getTotalSamplingRequiredInZone() { + return getCalcifiedPiecesSamplingDefinition().getZoneLimitation(); + } + + public boolean isTotalInCruiseAttained() { + return getTotalSamplingRequiredInCruise() > 0 && getSamplingCountInCruise() >= getTotalSamplingRequiredInCruise(); + } + + public boolean isTotalInFishingOperationAttained() { + return getTotalSamplingRequiredInFishingOperation() > 0 && getSamplingCountInFishingOperation() >= getTotalSamplingRequiredInFishingOperation(); + } + + public boolean isTotalInZoneAttained() { + return getTotalSamplingRequiredInZone() > 0 && getSamplingCountInZone() >= getTotalSamplingRequiredInZone(); + } + + public boolean isOneTotalCountIsAttained() { + return isTotalInCruiseAttained() || isTotalInZoneAttained() || isTotalInFishingOperationAttained(); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java new file mode 100644 index 0000000..7bfc5db --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java @@ -0,0 +1,29 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +import java.util.Objects; + +/** + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public abstract class IndividualObservationSamplingStatusExceptionSupport extends Exception { + + private final IndividualObservationBatch individualObservationBatch; + + public IndividualObservationSamplingStatusExceptionSupport(IndividualObservationBatch individualObservationBatch) { + Objects.requireNonNull(individualObservationBatch); + this.individualObservationBatch = individualObservationBatch; + } + + public IndividualObservationBatch getIndividualObservationBatch() { + return individualObservationBatch; + } + + public FishingOperation getFishingOperation() { + return individualObservationBatch.getFishingOperation(); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java index 79f204c..f06583c 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java @@ -24,10 +24,6 @@ package fr.ifremer.tutti.service.sampling; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; -import fr.ifremer.tutti.persistence.entities.protocol.Zone; -import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; - import java.util.EventObject; /** @@ -36,65 +32,11 @@ import java.util.EventObject; */ public class SamplingEvent extends EventObject { - protected final int lengthStep; - - protected final CaracteristicQualitativeValue gender; - - protected final Boolean maturity; - - protected final CalcifiedPiecesSamplingDefinition cpsDef; - - protected final Zone zone; - - protected final int nbSamplingForCruise; - - protected final int nbSamplingForZone; + private final IndividualObservationSamplingStatus status; - protected final int nbSamplingForOperation; - - public SamplingEvent(CruiseSamplingCache source, int lengthStep, CaracteristicQualitativeValue gender, Boolean maturity, - CalcifiedPiecesSamplingDefinition cpsDef, Zone zone, int nbSamplingForCruise, int nbSamplingForZone, int nbSamplingForOperation) { + public SamplingEvent(CruiseSamplingCache source, IndividualObservationSamplingStatus status) { super(source); - this.lengthStep = lengthStep; - this.gender = gender; - this.maturity = maturity; - this.cpsDef = cpsDef; - this.zone = zone; - this.nbSamplingForCruise = nbSamplingForCruise; - this.nbSamplingForZone = nbSamplingForZone; - this.nbSamplingForOperation = nbSamplingForOperation; - } - - public int getLengthStep() { - return lengthStep; - } - - public CaracteristicQualitativeValue getGender() { - return gender; - } - - public Boolean getMaturity() { - return maturity; - } - - public CalcifiedPiecesSamplingDefinition getCpsDef() { - return cpsDef; - } - - public Zone getZone() { - return zone; - } - - public int getNbSamplingForCruise() { - return nbSamplingForCruise; - } - - public int getNbSamplingForZone() { - return nbSamplingForZone; - } - - public int getNbSamplingForOperation() { - return nbSamplingForOperation; + this.status = status; } @Override @@ -102,4 +44,8 @@ public class SamplingEvent extends EventObject { return (CruiseSamplingCache) super.getSource(); } + public IndividualObservationSamplingStatus getStatus() { + return status; + } + } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java index f120f10..8f14783 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java @@ -34,6 +34,5 @@ public interface SamplingListener extends EventListener { void samplingNeeded(SamplingEvent event); - void summaryUpdated(SamplingEvent event); } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java new file mode 100644 index 0000000..8a5ac44 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand la taille n'est pas définie sur l'observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class SizeNotDefinedOnIndividualObservationException extends IndividualObservationSamplingStatusExceptionSupport { + + public SizeNotDefinedOnIndividualObservationException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java new file mode 100644 index 0000000..8a0cdb1 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand la zone n'est pas définie sur l'opération de pêche de l'observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ZoneNotDefinedOnFishingOperationException extends IndividualObservationSamplingStatusExceptionSupport { + + public ZoneNotDefinedOnFishingOperationException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.