1 package fr.ifremer.tutti.service;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Function;
26 import com.google.common.base.Preconditions;
27 import com.google.common.base.Predicate;
28 import com.google.common.collect.ImmutableSet;
29 import com.google.common.collect.Lists;
30 import com.google.common.collect.Multimap;
31 import fr.ifremer.adagio.core.dao.referential.ObjectTypeCode;
32 import fr.ifremer.tutti.TuttiConfiguration;
33 import fr.ifremer.tutti.persistence.InvalidBatchModelException;
34 import fr.ifremer.tutti.persistence.TuttiPersistence;
35 import fr.ifremer.tutti.persistence.TuttiPersistenceNoDbImpl;
36 import fr.ifremer.tutti.persistence.entities.CaracteristicMap;
37 import fr.ifremer.tutti.persistence.entities.TuttiEntities;
38 import fr.ifremer.tutti.persistence.entities.TuttiEntity;
39 import fr.ifremer.tutti.persistence.entities.data.AccidentalBatch;
40 import fr.ifremer.tutti.persistence.entities.data.Attachment;
41 import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
42 import fr.ifremer.tutti.persistence.entities.data.CatchBatch;
43 import fr.ifremer.tutti.persistence.entities.data.Cruise;
44 import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
45 import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch;
46 import fr.ifremer.tutti.persistence.entities.data.MarineLitterBatch;
47 import fr.ifremer.tutti.persistence.entities.data.Program;
48 import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
49 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
50 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
51 import fr.ifremer.tutti.persistence.entities.protocol.MaturityCaracteristic;
52 import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol;
53 import fr.ifremer.tutti.persistence.entities.protocol.Zones;
54 import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
55 import fr.ifremer.tutti.persistence.entities.referential.Gear;
56 import fr.ifremer.tutti.persistence.entities.referential.Gears;
57 import fr.ifremer.tutti.persistence.entities.referential.ObjectType;
58 import fr.ifremer.tutti.persistence.entities.referential.Person;
59 import fr.ifremer.tutti.persistence.entities.referential.Persons;
60 import fr.ifremer.tutti.persistence.entities.referential.Species;
61 import fr.ifremer.tutti.persistence.entities.referential.Speciess;
62 import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation;
63 import fr.ifremer.tutti.persistence.entities.referential.TuttiReferentialEntity;
64 import fr.ifremer.tutti.persistence.entities.referential.Vessel;
65 import fr.ifremer.tutti.persistence.entities.referential.Vessels;
66 import fr.ifremer.tutti.persistence.model.ProgramDataModel;
67 import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator;
68 import fr.ifremer.tutti.persistence.service.UpdateSchemaContextSupport;
69 import fr.ifremer.tutti.service.cruise.CruiseCache;
70 import fr.ifremer.tutti.service.cruise.CruiseCacheLoader;
71 import fr.ifremer.tutti.service.sampling.CruiseSamplingCache;
72 import org.apache.commons.collections4.CollectionUtils;
73 import org.apache.commons.io.IOUtils;
74 import org.apache.commons.logging.Log;
75 import org.apache.commons.logging.LogFactory;
76 import org.apache.commons.vfs2.AllFileSelector;
77 import org.apache.commons.vfs2.FileName;
78 import org.apache.commons.vfs2.FileObject;
79 import org.apache.commons.vfs2.FileType;
80 import org.nuiton.jaxx.application.ApplicationBusinessException;
81 import org.nuiton.jaxx.application.ApplicationIOUtil;
82 import org.nuiton.util.TimeLog;
83 import org.nuiton.version.Version;
84
85 import java.io.File;
86 import java.io.IOException;
87 import java.text.DateFormat;
88 import java.text.SimpleDateFormat;
89 import java.util.ArrayList;
90 import java.util.Collection;
91 import java.util.Collections;
92 import java.util.Iterator;
93 import java.util.LinkedHashSet;
94 import java.util.List;
95 import java.util.Map;
96 import java.util.Objects;
97 import java.util.Optional;
98 import java.util.Set;
99 import java.util.concurrent.Callable;
100
101 import static org.nuiton.i18n.I18n.t;
102
103
104
105
106
107
108
109 public class PersistenceService extends AbstractTuttiService implements TuttiPersistence {
110
111
112 private static final Log log = LogFactory.getLog(PersistenceService.class);
113
114 protected TuttiPersistence driver;
115
116 @Override
117 public void setServiceContext(TuttiServiceContext context) {
118 super.setServiceContext(context);
119
120 init();
121 }
122
123 public void setSampleCategoryModel(SampleCategoryModel sampleCategoryModel) {
124 context.getDataContext().setSampleCategoryModel(sampleCategoryModel);
125 }
126
127 public List<Gear> retainTemporaryGearList(List<Gear> targetList) {
128
129 return retainTemporaryList(Gears.IS_TEMPORARY, targetList);
130
131 }
132
133 public List<Person> retainTemporaryPersonList(List<Person> targetList) {
134
135 return retainTemporaryList(Persons.IS_TEMPORARY, targetList);
136
137 }
138
139 public List<Species> retainTemporarySpeciesList(List<Species> targetList) {
140
141 return retainTemporaryList(Speciess.IS_TEMPORARY, targetList);
142
143 }
144
145 public List<Vessel> retainTemporaryVesselList(List<Vessel> targetList) {
146
147 return retainTemporaryList(Vessels.IS_TEMPORARY, targetList);
148
149 }
150
151
152 public <E extends TuttiEntity> List<E> retainTemporaryList(Predicate<E> isTemporaryPredicate, List<E> targetList) {
153 List<E> sourceList = new ArrayList<>();
154 Iterator<E> iterator = targetList.iterator();
155 while (iterator.hasNext()) {
156 E next = iterator.next();
157 if (isTemporaryPredicate.apply(next)) {
158 iterator.remove();
159 sourceList.add(next);
160 }
161 }
162 return sourceList;
163 }
164
165 public interface FrequencyFunction extends Function<SpeciesBatch, List<SpeciesBatchFrequency>> {
166 }
167
168 public FrequencyFunction newSpeciesFrequenciesFunction() {
169 return input -> getAllSpeciesBatchFrequency(input.getIdAsInt());
170 }
171
172 public FrequencyFunction newBenthosFrequenciesFunction() {
173 return input -> getAllBenthosBatchFrequency(input.getIdAsInt());
174 }
175
176 public Float countFrequenciesWeight(List<SpeciesBatchFrequency> frequencies, boolean stopIfNullFound) {
177 Float result = null;
178 for (SpeciesBatchFrequency frequency : frequencies) {
179 Float w = frequency.getWeight();
180 if (w == null) {
181
182 if (stopIfNullFound) {
183 break;
184 }
185 continue;
186 }
187 if (result == null) {
188 result = 0f;
189 }
190 result += w;
191 }
192 return result;
193 }
194
195 public Integer countFrequenciesNumber(List<SpeciesBatchFrequency> frequencies, boolean stopIfNullFound) {
196 Integer result = null;
197 for (SpeciesBatchFrequency frequency : frequencies) {
198 Integer number = frequency.getNumber();
199 if (number == null) {
200
201 if (stopIfNullFound) {
202 break;
203 }
204 continue;
205 }
206 if (result == null) {
207 result = 0;
208 }
209 result += number;
210 }
211 return result;
212 }
213
214
215
216
217
218 @Override
219 public String getImplementationName() {
220 return "Tutti Persistence Service";
221 }
222
223 @Override
224 public void setSkipShutdownDbWhenClosing() {
225 driver.setSkipShutdownDbWhenClosing();
226 }
227
228 @Override
229 public ProgramDataModel loadProgram(String programId, boolean loadFishingOperation) {
230 return driver.loadProgram(programId, loadFishingOperation);
231 }
232
233 @Override
234 public ProgramDataModel loadCruises(String programId, boolean loadFishingOperation, Integer... cruiseIds) {
235 return driver.loadCruises(programId, loadFishingOperation, cruiseIds);
236 }
237
238 @Override
239 public ProgramDataModel loadCruise(String programId, Integer cruiseId, Integer... fishingOperationIds) {
240 return driver.loadCruise(programId, cruiseId, fishingOperationIds);
241 }
242
243 @Override
244 public void lazyInit() {
245
246 }
247
248 @Override
249 public void clearAllCaches() {
250 driver.clearAllCaches();
251 }
252
253 @Override
254 public <V> V invoke(Callable<V> call) {
255 return driver.invoke(call);
256 }
257
258 @Override
259 public <U extends UpdateSchemaContextSupport> void prepareUpdateSchemaContext(U context) {
260 driver.prepareUpdateSchemaContext(context);
261 }
262
263 @Override
264 public Version getSchemaVersion() {
265 return driver.getSchemaVersion();
266 }
267
268 @Override
269 public Version getSchemaVersionIfUpdate() {
270 return driver.getSchemaVersionIfUpdate();
271 }
272
273 @Override
274 public void updateSchema() {
275 driver.updateSchema();
276 }
277
278 @Override
279 public void sanityDb() {
280 driver.sanityDb();
281 }
282
283 public static final DateFormat EXPORT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
284
285 public static final String EXPORT_DIRECTORY_FORMAT = "tutti-%s-%s";
286
287
288
289
290
291
292
293 public void exportDb(File file) {
294
295
296 Preconditions.checkState(!isDbLoaded());
297
298
299 Preconditions.checkNotNull(file);
300
301
302
303 TuttiConfiguration config = context.getConfig();
304
305 String directoryName = String.format(
306 EXPORT_DIRECTORY_FORMAT,
307 config.getVersion(),
308 EXPORT_DATE_FORMAT.format(context.currentDate()));
309
310 File structureDirectory = new File(config.newTempFile("exportdb"),
311 directoryName);
312
313 try {
314 ApplicationIOUtil.forceMkdir(structureDirectory,
315 t("tutti.io.mkDir.error", structureDirectory));
316
317 if (log.isInfoEnabled()) {
318 log.info("Export directory: " + structureDirectory);
319 }
320
321 ApplicationIOUtil.copyDirectory(config.getDbDirectory(),
322 new File(structureDirectory, "db"),
323 t("tutti.service.persistence.copyDirectory.db.error"));
324
325 ApplicationIOUtil.copyDirectory(config.getDbAttachmentDirectory(),
326 new File(structureDirectory, "meas_files"),
327 t("tutti.service.persistence.copyDirectory.attachment.error"));
328
329
330 ApplicationIOUtil.zip(structureDirectory, file,
331 t("tutti.service.persistence.exportDb.zip.error", file));
332
333 } finally {
334
335
336 ApplicationIOUtil.forceDeleteOnExit(
337 structureDirectory,
338 t("tutti.service.persistence.exportDb.deleteTempDir.error", structureDirectory));
339 }
340 }
341
342 public enum ImportStructureType {
343 NORMAL,
344 INLINE
345 }
346
347 public ImportStructureType checkImportStructure(File file) {
348
349 if (!file.exists()) {
350 throw new ApplicationBusinessException(t("tutti.service.persistence.checkImportstructure.fileNotExist", file));
351 }
352
353
354 FileObject fileObject = ApplicationIOUtil.resolveFile(
355 "zip:" + file.getAbsolutePath(), t("tutti.service.persistence.getArchive.error", file));
356
357
358 FileObject[] children = ApplicationIOUtil.getChildren(fileObject, t("tutti.service.persistence.openArchive.error", file));
359
360 if (children.length != 1) {
361 throw new ApplicationBusinessException(t("tutti.service.persistence.checkImportstructure.tooManyChildren", file));
362 }
363
364 ImportStructureType result;
365
366 fileObject = children[0];
367 children = ApplicationIOUtil.getChildren(fileObject, t("tutti.service.persistence.openArchive.error", file));
368
369
370 boolean dbDirectoyDetected = false;
371 for (FileObject child : children) {
372 FileName name = child.getName();
373 if (name.getBaseName().equals("db")) {
374 dbDirectoyDetected = true;
375 break;
376 }
377 }
378
379 if (dbDirectoyDetected) {
380
381
382 result = ImportStructureType.NORMAL;
383
384 checkArchiveDb(file, fileObject, "db", true);
385 checkArchiveDb(file, fileObject, "meas_files", false);
386 } else {
387
388
389 result = ImportStructureType.INLINE;
390
391
392 for (FileObject child : children) {
393 FileType type = ApplicationIOUtil.getType(child, "Could not get type of " + child);
394 if (FileType.FOLDER.equals(type)) {
395 throw new ApplicationBusinessException(t("tutti.service.persistence.checkImportstructure.inlineForbidDirectory"));
396 }
397 }
398 }
399
400 if (log.isInfoEnabled()) {
401 log.info("Database import type: " + result);
402 }
403
404 return result;
405 }
406
407 protected void checkArchiveDb(File file,
408 FileObject fileObject,
409 String dir,
410 boolean required) {
411 FileObject directory = ApplicationIOUtil.getChild(fileObject, dir, t("tutti.service.persistence.getChild.error", dir));
412 if (directory == null) {
413
414 String message = t("tutti.service.persistence.checkArchiveDb.error", file, dir);
415 if (required) {
416 throw new ApplicationBusinessException(message);
417 }
418
419 if (log.isWarnEnabled()) {
420 log.warn(message);
421 }
422 }
423 }
424
425
426
427
428
429
430
431
432 public void importDb(ImportStructureType importStructureType, File file) {
433
434
435 Preconditions.checkState(!isDbLoaded());
436
437
438 Preconditions.checkNotNull(file);
439
440 TuttiConfiguration config = context.getConfig();
441
442 File target = config.getDataDirectory();
443
444 if (log.isInfoEnabled()) {
445 log.info("Import db to " + target);
446 }
447 FileObject fileObject = ApplicationIOUtil.resolveFile(
448 "zip:" + file.getAbsolutePath(),
449 t("tutti.service.persistence.getArchive.error", file));
450
451 FileObject[] children = ApplicationIOUtil.getChildren(
452 fileObject,
453 t("tutti.service.persistence.openArchive.error", file));
454
455 fileObject = children[0];
456
457 switch (importStructureType) {
458
459 case NORMAL:
460
461 break;
462
463 case INLINE:
464 target = new File(target, "db");
465 ApplicationIOUtil.forceMkdir(
466 target,
467 t("tutti.service.persistence.createDbDirectory.error", file));
468
469
470 break;
471 }
472
473 ApplicationIOUtil.explode(fileObject,
474 target,
475 new AllFileSelector(),
476 t("tutti.service.persistence.extractArchive.error", file));
477 }
478
479 public boolean isDbLoaded() {
480 return !(driver instanceof TuttiPersistenceNoDbImpl);
481 }
482
483 public List<Caracteristic> getDefaultIndividualObservationCaracteristics() {
484
485 TuttiProtocol protocol = getProtocol();
486
487 List<Caracteristic> result;
488 if (protocol != null) {
489 List<String> individualObservationPmfmId = getProtocol().getIndividualObservationPmfmId();
490 if (CollectionUtils.isEmpty(individualObservationPmfmId)) {
491
492
493 result = Lists.newArrayList();
494
495 } else {
496 result = Lists.newArrayListWithCapacity(individualObservationPmfmId.size());
497 for (String id : individualObservationPmfmId) {
498 Caracteristic caracteristic = getCaracteristic(Integer.valueOf(id));
499 result.add(caracteristic);
500 }
501 }
502
503 } else {
504
505 result = Lists.newArrayList();
506 }
507
508 return result;
509 }
510
511 public List<Caracteristic> getLengthStepCaracteristics(List<Caracteristic> caracteristics) {
512
513
514 TuttiProtocol protocol = getProtocol();
515
516 List<Caracteristic> result;
517 if (protocol != null) {
518
519 result = Lists.newArrayListWithCapacity(
520 protocol.sizeLengthClassesPmfmId());
521
522 Map<String, Caracteristic> allCaractericsById =
523 TuttiEntities.splitById(caracteristics);
524
525 if (!protocol.isLengthClassesPmfmIdEmpty()) {
526 for (String id : protocol.getLengthClassesPmfmId()) {
527 result.add(allCaractericsById.get(id));
528 }
529 }
530 } else {
531
532 result = Lists.newArrayList();
533 }
534
535
536 result = Collections.unmodifiableList(result);
537 return result;
538 }
539
540 public List<Caracteristic> getMaturityCaracteristics(List<Caracteristic> caracteristics) {
541
542
543 TuttiProtocol protocol = getProtocol();
544
545 List<Caracteristic> result;
546 if (protocol != null) {
547
548 result = Lists.newArrayListWithCapacity(
549 protocol.sizeMaturityCaracteristics());
550
551 Map<String, Caracteristic> allCaractericsById =
552 TuttiEntities.splitById(caracteristics);
553
554 if (!protocol.isMaturityCaracteristicsEmpty()) {
555 for (MaturityCaracteristic caracteristic : protocol.getMaturityCaracteristics()) {
556 result.add(allCaractericsById.get(caracteristic.getId()));
557 }
558 }
559 } else {
560
561 result = Lists.newArrayList();
562 }
563
564
565 result = Collections.unmodifiableList(result);
566 return result;
567 }
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591 public static final TimeLog TIME_LOG = new TimeLog(PersistenceService.class);
592
593 @Override
594 public void init() {
595
596 long t0 = TimeLog.getTime();
597
598 if (log.isDebugEnabled()) {
599 log.debug("Opening persistence service...");
600 }
601
602 TuttiConfiguration config = context.getConfig();
603 TuttiConfiguration.setInstance(config);
604 if (config.isDbExists()) {
605
606 String jdbcUrl = config.getJdbcUrl();
607 if (log.isInfoEnabled()) {
608 log.info("Using database at " + jdbcUrl);
609 }
610
611 driver = TuttiPersistenceServiceLocator.getPersistenceService();
612
613 if (config.isSanityDb()) {
614
615 driver.sanityDb();
616 }
617
618 } else {
619
620 driver = new TuttiPersistenceNoDbImpl();
621
622 driver.init();
623 }
624
625 TIME_LOG.log(t0, "Persistence driver *" + driver.getImplementationName() + "* opened.");
626 }
627
628 @Override
629 public void close() throws IOException {
630
631 long t0 = TimeLog.getTime();
632
633 String driverName = driver.getImplementationName();
634
635 if (log.isDebugEnabled()) {
636 log.debug("Closing persistence Service *" + driverName + "*...");
637 }
638
639 IOUtils.closeQuietly(driver);
640
641 TIME_LOG.log(t0, "Persistence driver *" + driverName + "* closed.");
642 }
643
644
645
646
647
648 public List<Vessel> getAllVessel() {
649 List<Vessel> targetList = Lists.newArrayList(getAllFishingVessel());
650 targetList.addAll(getAllScientificVessel());
651 return targetList;
652 }
653
654 @Override
655 public List<Vessel> getAllScientificVessel() {
656 return driver.getAllScientificVessel();
657 }
658
659 @Override
660 public List<Vessel> getAllFishingVessel() {
661 return driver.getAllFishingVessel();
662 }
663
664 @Override
665 public List<Vessel> getAllVesselWithObsoletes() {
666 return driver.getAllVesselWithObsoletes();
667 }
668
669 @Override
670 public List<Species> getAllSpecies() {
671 return driver.getAllSpecies();
672 }
673
674 @Override
675 public List<Species> getAllReferentSpecies() {
676 return driver.getAllReferentSpecies();
677 }
678
679 @Override
680 public List<Species> getAllReferentSpeciesWithObsoletes() {
681 return driver.getAllReferentSpeciesWithObsoletes();
682 }
683
684 @Override
685 public Species getSpeciesByReferenceTaxonId(Integer referenceTaxonId) {
686 return driver.getSpeciesByReferenceTaxonId(referenceTaxonId);
687 }
688
689 @Override
690 public Species getSpeciesByReferenceTaxonIdWithVernacularCode(Integer referenceTaxonId) {
691 return driver.getSpeciesByReferenceTaxonIdWithVernacularCode(referenceTaxonId);
692 }
693
694 @Override
695 public Map<Integer, Integer> getAllObsoleteReferentTaxons() {
696 return driver.getAllObsoleteReferentTaxons();
697 }
698
699 @Override
700 public List<Caracteristic> getAllCaracteristic() {
701 return driver.getAllCaracteristic();
702 }
703
704 @Override
705 public List<Caracteristic> getAllCaracteristicWithProtected() {
706 return driver.getAllCaracteristicWithProtected();
707 }
708
709 @Override
710 public List<Caracteristic> getAllCaracteristicForSampleCategory() {
711 return driver.getAllCaracteristicForSampleCategory();
712 }
713
714 @Override
715 public List<Caracteristic> getAllNumericCaracteristic() {
716 return driver.getAllNumericCaracteristic();
717 }
718
719 @Override
720 public List<TuttiLocation> getAllProgramZone() {
721 return driver.getAllProgramZone();
722 }
723
724 @Override
725 public List<TuttiLocation> getAllCountry() {
726 return driver.getAllCountry();
727 }
728
729 @Override
730 public List<TuttiLocation> getAllHarbour() {
731 return driver.getAllHarbour();
732 }
733
734 @Override
735 public List<TuttiLocation> getAllHarbourWithObsoletes() {
736 return driver.getAllHarbourWithObsoletes();
737 }
738
739 @Override
740 public TuttiLocation getLocation(String id) {
741 return driver.getLocation(id);
742 }
743
744 public List<Gear> getAllGear() {
745 List<Gear> targetList = Lists.newArrayList(getAllScientificGear());
746 targetList.addAll(getAllFishingGear());
747 return targetList;
748 }
749
750 @Override
751 public List<Gear> getAllScientificGear() {
752 return driver.getAllScientificGear();
753 }
754
755 @Override
756 public List<Gear> getAllFishingGear() {
757 return driver.getAllFishingGear();
758 }
759
760 @Override
761 public List<Gear> getAllGearWithObsoletes() {
762 return driver.getAllGearWithObsoletes();
763 }
764
765 @Override
766 public List<Person> getAllPerson() {
767 return driver.getAllPerson();
768 }
769
770 @Override
771 public List<Person> getAllPersonWithObsoletes() {
772 return driver.getAllPersonWithObsoletes();
773 }
774
775 @Override
776 public List<ObjectType> getAllObjectType() {
777 return driver.getAllObjectType();
778 }
779
780 @Override
781 public ImmutableSet<Integer> getAllFishingOperationStratasAndSubstratasIdsForProgram(String zoneId) {
782 return driver.getAllFishingOperationStratasAndSubstratasIdsForProgram(zoneId);
783 }
784
785 @Override
786 public Multimap<TuttiLocation, TuttiLocation> getAllFishingOperationStratasAndSubstratas(String zoneId) {
787 return driver.getAllFishingOperationStratasAndSubstratas(zoneId);
788 }
789
790 @Override
791 public List<TuttiLocation> getAllFishingOperationStrata(String zoneId) {
792 return driver.getAllFishingOperationStrata(zoneId);
793 }
794
795 @Override
796 public List<TuttiLocation> getAllFishingOperationStrataWithObsoletes(String zoneId) {
797 return driver.getAllFishingOperationStrataWithObsoletes(zoneId);
798 }
799
800 @Override
801 public List<TuttiLocation> getAllFishingOperationSubStrata(String zoneId, String strataId) {
802 return driver.getAllFishingOperationSubStrata(zoneId, strataId);
803 }
804
805 @Override
806 public List<TuttiLocation> getAllFishingOperationSubStrataWithObsoletes(String zoneId, String strataId) {
807 return driver.getAllFishingOperationSubStrataWithObsoletes(zoneId, strataId);
808 }
809
810 @Override
811 public List<TuttiLocation> getAllFishingOperationLocation(String zoneId, String strataId, String subStrataId) {
812 return driver.getAllFishingOperationLocation(zoneId, strataId, subStrataId);
813 }
814
815 @Override
816 public List<TuttiLocation> getAllFishingOperationLocationWithObsoletes(String zoneId, String strataId, String subStrataId) {
817 return driver.getAllFishingOperationLocationWithObsoletes(zoneId, strataId, subStrataId);
818 }
819
820 @Override
821 public Caracteristic getSizeCategoryCaracteristic() {
822 return driver.getSizeCategoryCaracteristic();
823 }
824
825 @Override
826 public Caracteristic getSexCaracteristic() {
827 return driver.getSexCaracteristic();
828 }
829
830 @Override
831 public Caracteristic getSortedUnsortedCaracteristic() {
832 return driver.getSortedUnsortedCaracteristic();
833 }
834
835 @Override
836 public Caracteristic getMaturityCaracteristic() {
837 return driver.getMaturityCaracteristic();
838 }
839
840 @Override
841 public Caracteristic getAgeCaracteristic() {
842 return driver.getAgeCaracteristic();
843 }
844
845 @Override
846 public Caracteristic getMarineLitterCategoryCaracteristic() {
847 return driver.getMarineLitterCategoryCaracteristic();
848 }
849
850 @Override
851 public Caracteristic getMarineLitterSizeCategoryCaracteristic() {
852 return driver.getMarineLitterSizeCategoryCaracteristic();
853 }
854
855 @Override
856 public Caracteristic getVerticalOpeningCaracteristic() {
857 return driver.getVerticalOpeningCaracteristic();
858 }
859
860 @Override
861 public Caracteristic getHorizontalOpeningWingsCaracteristic() {
862 return driver.getHorizontalOpeningWingsCaracteristic();
863 }
864
865 @Override
866 public Caracteristic getHorizontalOpeningDoorCaracteristic() {
867 return driver.getHorizontalOpeningDoorCaracteristic();
868 }
869
870 @Override
871 public Caracteristic getDeadOrAliveCaracteristic() {
872 return driver.getDeadOrAliveCaracteristic();
873 }
874
875 @Override
876 public Caracteristic getCalcifiedStructureCaracteristic() {
877 return driver.getCalcifiedStructureCaracteristic();
878 }
879
880 @Override
881 public Caracteristic getPmfmIdCaracteristic() {
882 return driver.getPmfmIdCaracteristic();
883 }
884
885 @Override
886 public Caracteristic getWeightMeasuredCaracteristic() {
887 return driver.getWeightMeasuredCaracteristic();
888 }
889
890 @Override
891 public Caracteristic getCopyIndividualObservationModeCaracteristic() {
892 return driver.getCopyIndividualObservationModeCaracteristic();
893 }
894
895 @Override
896 public Caracteristic getSampleCodeCaracteristic() {
897 return driver.getSampleCodeCaracteristic();
898 }
899
900 @Override
901 public Caracteristic getCaracteristic(Integer pmfmId) {
902 return driver.getCaracteristic(pmfmId);
903 }
904
905 @Override
906 public boolean isVracBatch(SpeciesBatch speciesBatch) {
907 return driver.isVracBatch(speciesBatch);
908 }
909
910 @Override
911 public boolean isHorsVracBatch(SpeciesBatch speciesBatch) {
912 return driver.isHorsVracBatch(speciesBatch);
913 }
914
915 @Override
916 public Predicate<SpeciesBatch> getVracBatchPredicate() {
917 return driver.getVracBatchPredicate();
918 }
919
920 @Override
921 public boolean isTemporary(TuttiReferentialEntity entity) {
922 return driver.isTemporary(entity);
923 }
924
925 @Override
926 public Vessel getVessel(String vesselCode) {
927 return driver.getVessel(vesselCode);
928 }
929
930 @Override
931 public Person getPerson(Integer personId) {
932 return driver.getPerson(personId);
933 }
934
935 @Override
936 public Gear getGear(Integer gearCode) {
937 return driver.getGear(gearCode);
938 }
939
940 @Override
941 public ObjectType getObjectType(String objectTypeCode) {
942 return driver.getObjectType(objectTypeCode);
943 }
944
945 @Override
946 public List<Gear> addTemporaryGears(List<Gear> gears) {
947 return driver.addTemporaryGears(gears);
948 }
949
950 @Override
951 public List<Person> addTemporaryPersons(List<Person> persons) {
952 return driver.addTemporaryPersons(persons);
953 }
954
955 @Override
956 public List<Species> addTemporarySpecies(List<Species> species) {
957 return driver.addTemporarySpecies(species);
958 }
959
960 @Override
961 public List<Vessel> addTemporaryVessels(List<Vessel> vessels) {
962 return driver.addTemporaryVessels(vessels);
963 }
964
965 @Override
966 public List<Gear> updateTemporaryGears(List<Gear> gears) {
967 return driver.updateTemporaryGears(gears);
968 }
969
970 @Override
971 public List<Person> updateTemporaryPersons(List<Person> persons) {
972 return driver.updateTemporaryPersons(persons);
973 }
974
975 @Override
976 public List<Species> updateTemporarySpecies(List<Species> species) {
977 return driver.updateTemporarySpecies(species);
978 }
979
980 @Override
981 public List<Vessel> updateTemporaryVessels(List<Vessel> vessels) {
982 return driver.updateTemporaryVessels(vessels);
983 }
984
985 @Override
986 public List<Gear> linkTemporaryGears(List<Gear> gears) {
987 return driver.linkTemporaryGears(gears);
988 }
989
990 @Override
991 public List<Person> linkTemporaryPersons(List<Person> persons) {
992 return driver.linkTemporaryPersons(persons);
993 }
994
995 @Override
996 public List<Species> linkTemporarySpecies(List<Species> specieses) {
997 return driver.linkTemporarySpecies(specieses);
998 }
999
1000 @Override
1001 public List<Vessel> linkTemporaryVessels(List<Vessel> vessels) {
1002 return driver.linkTemporaryVessels(vessels);
1003 }
1004
1005 @Override
1006 public void replaceGear(Gear source, Gear target, boolean delete) {
1007 driver.replaceGear(source, target, delete);
1008 }
1009
1010 @Override
1011 public void replacePerson(Person source, Person target, boolean delete) {
1012 driver.replacePerson(source, target, delete);
1013 }
1014
1015 @Override
1016 public void replaceSpecies(Species source, Species target, boolean delete) {
1017 driver.replaceSpecies(source, target, delete);
1018 }
1019
1020 @Override
1021 public void replaceVessel(Vessel source, Vessel target, boolean delete) {
1022 driver.replaceVessel(source, target, delete);
1023 }
1024
1025 @Override
1026 public void deleteTemporaryGear(Integer id) {
1027 driver.deleteTemporaryGear(id);
1028 }
1029
1030 @Override
1031 public void deleteTemporaryGears(Collection<Integer> id) {
1032 driver.deleteTemporaryGears(id);
1033 }
1034
1035 @Override
1036 public void deleteTemporarySpecies(Integer referenceTaxonId) {
1037 driver.deleteTemporarySpecies(referenceTaxonId);
1038 }
1039
1040 @Override
1041 public void deleteTemporarySpecies(Collection<Integer> referenceTaxonIds) {
1042 driver.deleteTemporarySpecies(referenceTaxonIds);
1043 }
1044
1045 @Override
1046 public void deleteTemporaryPerson(Integer id) {
1047 driver.deleteTemporaryPerson(id);
1048 }
1049
1050 @Override
1051 public void deleteTemporaryPersons(Collection<Integer> ids) {
1052 driver.deleteTemporaryPersons(ids);
1053 }
1054
1055 @Override
1056 public void deleteTemporaryVessel(String code) {
1057 driver.deleteTemporaryVessel(code);
1058 }
1059
1060 @Override
1061 public void deleteTemporaryVessels(Collection<String> codes) {
1062 driver.deleteTemporaryVessels(codes);
1063 }
1064
1065 @Override
1066 public boolean isTemporaryPersonUsed(Integer id) {
1067 return driver.isTemporaryPersonUsed(id);
1068 }
1069
1070 @Override
1071 public boolean isTemporarySpeciesUsed(Integer referenceTaxonId) {
1072 return driver.isTemporarySpeciesUsed(referenceTaxonId);
1073 }
1074
1075 @Override
1076 public boolean isTemporaryGearUsed(Integer id) {
1077 return driver.isTemporaryGearUsed(id);
1078 }
1079
1080 @Override
1081 public boolean isTemporaryVesselUsed(String code) {
1082 return driver.isTemporaryVesselUsed(code);
1083 }
1084
1085 @Override
1086 public String getLocationLabelByLatLong(Float latitude, Float longitude) {
1087 return driver.getLocationLabelByLatLong(latitude, longitude);
1088 }
1089
1090 @Override
1091 public Integer getLocationIdByLatLong(Float latitude, Float longitude) {
1092 return driver.getLocationIdByLatLong(latitude, longitude);
1093 }
1094
1095
1096
1097
1098
1099 @Override
1100 public List<Attachment> getAllAttachments(ObjectTypeCode objectType, Integer objectId) {
1101 return driver.getAllAttachments(objectType, objectId);
1102 }
1103
1104 @Override
1105 public File getAttachmentFile(String attachmentId) {
1106 return driver.getAttachmentFile(attachmentId);
1107 }
1108
1109 @Override
1110 public Attachment createAttachment(Attachment attachment, File file) {
1111 return driver.createAttachment(attachment, file);
1112 }
1113
1114 @Override
1115 public Attachment saveAttachment(Attachment attachment) {
1116 return driver.saveAttachment(attachment);
1117 }
1118
1119 @Override
1120 public void deleteAttachment(String attachmentId) {
1121 driver.deleteAttachment(attachmentId);
1122 }
1123
1124 @Override
1125 public void deleteAllAttachment(ObjectTypeCode objectType, Set<Integer> objectIds) {
1126 driver.deleteAllAttachment(objectType, objectIds);
1127 }
1128
1129 @Override
1130 public void deleteAllAttachment(ObjectTypeCode objectType, Integer objectId) {
1131 driver.deleteAllAttachment(objectType, objectId);
1132 }
1133
1134
1135
1136
1137
1138 @Override
1139 public List<Program> getAllProgram() {
1140 return driver.getAllProgram();
1141 }
1142
1143 @Override
1144 public Program getProgram(String id) {
1145 return driver.getProgram(id);
1146 }
1147
1148 @Override
1149 public Program createProgram(Program bean) {
1150 return driver.createProgram(bean);
1151 }
1152
1153 @Override
1154 public Program saveProgram(Program bean) {
1155 return driver.saveProgram(bean);
1156 }
1157
1158
1159
1160
1161
1162 @Override
1163 public List<Integer> getAllCruiseId(String programId) {
1164 return driver.getAllCruiseId(programId);
1165 }
1166
1167 @Override
1168 public List<Cruise> getAllCruise(String programId) {
1169 return driver.getAllCruise(programId);
1170 }
1171
1172 @Override
1173 public Cruise getCruise(Integer id) {
1174 return driver.getCruise(id);
1175 }
1176
1177 @Override
1178 public Cruise createCruise(Cruise bean) {
1179 return driver.createCruise(bean);
1180 }
1181
1182 @Override
1183 public Cruise saveCruise(Cruise bean, boolean updateVessel, boolean updateGear) {
1184 return driver.saveCruise(bean, updateVessel, updateGear);
1185 }
1186
1187 @Override
1188 public void setCruiseReadyToSynch(Integer cruiseId) {
1189 driver.setCruiseReadyToSynch(cruiseId);
1190 }
1191
1192 @Override
1193 public CaracteristicMap getGearCaracteristics(Integer cruiseId, Integer gearId, short rankOrder) {
1194 return driver.getGearCaracteristics(cruiseId, gearId, rankOrder);
1195 }
1196
1197 @Override
1198 public boolean isOperationUseGears(Integer cruiseId, Collection<Gear> gears) {
1199 return driver.isOperationUseGears(cruiseId, gears);
1200 }
1201
1202 @Override
1203 public void saveGearCaracteristics(Gear gear, Cruise cruise) {
1204 driver.saveGearCaracteristics(gear, cruise);
1205 }
1206
1207
1208
1209
1210
1211
1212 @Override
1213 public TuttiProtocol getProtocol() {
1214 return driver.getProtocol();
1215 }
1216
1217 @Override
1218 public void setProtocol(TuttiProtocol protocol) {
1219 driver.setProtocol(protocol);
1220 }
1221
1222 @Override
1223 public boolean isProtocolExist(String id) {
1224 return driver.isProtocolExist(id);
1225 }
1226
1227 @Override
1228 public List<String> getAllProtocolNames() {
1229 return driver.getAllProtocolNames();
1230 }
1231
1232 @Override
1233 public String getFirstAvailableName(String protocolName) {
1234 return driver.getFirstAvailableName(protocolName);
1235 }
1236
1237 @Override
1238 public List<TuttiProtocol> getAllProtocol() {
1239 return driver.getAllProtocol();
1240 }
1241
1242 @Override
1243 public List<TuttiProtocol> getAllProtocol(String programId) {
1244 return driver.getAllProtocol(programId);
1245 }
1246
1247 @Override
1248 public List<String> getAllProtocolId() {
1249 return driver.getAllProtocolId();
1250 }
1251
1252 @Override
1253 public TuttiProtocol getProtocol(String id) {
1254 TuttiProtocol protocol = driver.getProtocol(id);
1255
1256 if (protocol.isUseCalcifiedPieceSampling() && context.getDataContext().isProgramFilled()) {
1257
1258
1259 Program program = context.getDataContext().getProgram();
1260
1261 String programZoneId = program.getZone().getId();
1262
1263 ImmutableSet<Integer> availableLocationIds = getAllFishingOperationStratasAndSubstratasIdsForProgram(programZoneId);
1264
1265 if (protocol.isUseCalcifiedPieceSampling() && !protocol.isZoneEmpty()) {
1266
1267 protocol.getZone().forEach(zone -> {
1268
1269 ImmutableSet<Integer> allLocationIds = Zones.getAllLocationIds(zone);
1270
1271 for (Integer locationId : allLocationIds) {
1272
1273 if (!availableLocationIds.contains(locationId)) {
1274
1275 throw new ApplicationBusinessException("Le protocole utilise une strate d'identifiant " + locationId + " non reconnue dans le système.");
1276
1277 }
1278 }
1279 });
1280 }
1281
1282 }
1283
1284 return protocol;
1285 }
1286
1287 @Override
1288 public TuttiProtocol getProtocolByName(String protocolName) {
1289 return driver.getProtocolByName(protocolName);
1290 }
1291
1292 @Override
1293 public TuttiProtocol createProtocol(TuttiProtocol bean) {
1294 return driver.createProtocol(bean);
1295 }
1296
1297 @Override
1298 public TuttiProtocol saveProtocol(TuttiProtocol bean) {
1299 return driver.saveProtocol(bean);
1300 }
1301
1302 @Override
1303 public void deleteProtocol(String id) {
1304 driver.deleteProtocol(id);
1305 }
1306
1307
1308
1309
1310
1311 @Override
1312 public int getFishingOperationCount(Integer cruiseId) {
1313 return driver.getFishingOperationCount(cruiseId);
1314 }
1315
1316 @Override
1317 public List<Integer> getAllFishingOperationIds(Integer cruiseId) {
1318 return driver.getAllFishingOperationIds(cruiseId);
1319 }
1320
1321 @Override
1322 public List<FishingOperation> getAllFishingOperation(Integer cruiseId) {
1323 return driver.getAllFishingOperation(cruiseId);
1324 }
1325
1326 @Override
1327 public FishingOperation getFishingOperation(Integer id) {
1328 FishingOperation bean = driver.getFishingOperation(id);
1329
1330 if (bean.getGearShootingEndDate() == null) {
1331 bean.setGearShootingEndDate(bean.getGearShootingStartDate());
1332 }
1333 return bean;
1334 }
1335
1336 @Override
1337 public List<Vessel> getFishingOperationSecondaryVessel(Integer fishingOperationId) {
1338 return driver.getFishingOperationSecondaryVessel(fishingOperationId);
1339 }
1340
1341 @Override
1342 public FishingOperation createFishingOperation(FishingOperation bean) {
1343
1344
1345 if (Objects.equals(bean.getGearShootingStartDate(), bean.getGearShootingEndDate())) {
1346 bean.setGearShootingEndDate(null);
1347 }
1348 return driver.createFishingOperation(bean);
1349 }
1350
1351 @Override
1352 public FishingOperation saveFishingOperation(FishingOperation bean) {
1353
1354 if (Objects.equals(bean.getGearShootingStartDate(), bean.getGearShootingEndDate())) {
1355 bean.setGearShootingEndDate(null);
1356 }
1357
1358 Optional<CruiseCache> optionalCruiseCache = getOptionalCruiseCache();
1359
1360 boolean reloadSamplingCache = false;
1361
1362 if (optionalCruiseCache.isPresent()) {
1363
1364 CruiseCache cruiseCache = optionalCruiseCache.get();
1365
1366 if (optionalCruiseCache.isPresent()) {
1367
1368 Optional<CruiseSamplingCache> optionalSamplingCruiseCache = cruiseCache.getSamplingCruiseCache();
1369
1370 if (optionalSamplingCruiseCache.isPresent()) {
1371
1372
1373 CruiseSamplingCache cruiseSamplingCache = optionalSamplingCruiseCache.get();
1374
1375 FishingOperation oldFishingOperation = getFishingOperation(bean.getIdAsInt());
1376
1377 boolean zoneChanged = cruiseSamplingCache.isZoneChanged(oldFishingOperation, bean);
1378
1379 if (zoneChanged) {
1380
1381
1382 if (log.isInfoEnabled()) {
1383 log.info("Zone has changed for fishingOperation: " + bean + ", remove fishing operation from cruise cache.");
1384 }
1385 reloadSamplingCache = true;
1386
1387 cruiseSamplingCache.printInfos("Before removing fishing operation");
1388
1389 List<IndividualObservationBatch> individualObservations = getAllIndividualObservationBatchsForFishingOperation(bean.getIdAsInt());
1390 cruiseCache.removeFishingOperation(oldFishingOperation, individualObservations);
1391
1392 }
1393
1394 }
1395
1396 }
1397
1398 }
1399
1400 FishingOperation fishingOperation = driver.saveFishingOperation(bean);
1401
1402 if (optionalCruiseCache.isPresent() && reloadSamplingCache) {
1403
1404 if (log.isInfoEnabled()) {
1405 log.info("Zone has changed for fishingOperation: " + bean + ", recompute fishing operation from cruise cache.");
1406 }
1407
1408 CruiseCache cruiseCache = optionalCruiseCache.get();
1409
1410 CruiseSamplingCache cruiseSamplingCache = cruiseCache.getSamplingCruiseCache().orElseGet(null);
1411
1412 cruiseSamplingCache.printInfos("Before loading " + fishingOperation);
1413
1414 CruiseCacheLoader cruiseCacheLoader = CruiseCacheLoader.newCacheLoader(this, context.getService(DecoratorService.class), null, cruiseCache);
1415 cruiseCacheLoader.loadCruiseCacheForFishingOperation(fishingOperation);
1416
1417 cruiseSamplingCache.printInfos("After loading " + fishingOperation);
1418
1419 }
1420
1421 return fishingOperation;
1422 }
1423
1424
1425 @Override
1426 public Collection<FishingOperation> saveFishingOperations(Collection<FishingOperation> beans) {
1427 return driver.saveFishingOperations(beans);
1428 }
1429
1430 @Override
1431 public void deleteFishingOperation(Integer id) {
1432 Optional<CruiseCache> optionalCruiseCache = getOptionalCruiseCache();
1433 if (optionalCruiseCache.isPresent()) {
1434
1435 CruiseCache cruiseCache = optionalCruiseCache.get();
1436 if (log.isInfoEnabled()) {
1437 log.info("Remove fishing operation: " + id + " from cruiseSamplingCache: " + cruiseCache);
1438 }
1439 FishingOperation fishingOperation = getFishingOperation(id);
1440
1441 List<IndividualObservationBatch> individualObservations = getAllIndividualObservationBatchsForFishingOperation(id);
1442
1443 optionalCruiseCache.get().removeFishingOperation(fishingOperation, individualObservations);
1444 }
1445 driver.deleteFishingOperation(id);
1446 }
1447
1448
1449
1450
1451
1452 @Override
1453 public boolean isFishingOperationWithCatchBatch(Integer operationId) {
1454 return driver.isFishingOperationWithCatchBatch(operationId);
1455 }
1456
1457 @Override
1458 public CatchBatch getCatchBatchFromFishingOperation(Integer id) throws InvalidBatchModelException {
1459 return driver.getCatchBatchFromFishingOperation(id);
1460
1461 }
1462
1463 @Override
1464 public CatchBatch createCatchBatch(CatchBatch bean) {
1465 return driver.createCatchBatch(bean);
1466 }
1467
1468 @Override
1469 public CatchBatch saveCatchBatch(CatchBatch bean) {
1470 return driver.saveCatchBatch(bean);
1471 }
1472
1473 @Override
1474 public void deleteCatchBatch(Integer fishingOperationId) {
1475 driver.deleteCatchBatch(fishingOperationId);
1476 }
1477
1478 @Override
1479 public void recomputeCatchBatchSampleRatios(Integer fishingOperationId) {
1480 driver.recomputeCatchBatchSampleRatios(fishingOperationId);
1481 }
1482
1483 @Override
1484 public Map getPrevOperationNameAndBatchId(int operationId, int taxonId) {
1485 return driver.getPrevOperationNameAndBatchId(operationId, taxonId);
1486 }
1487
1488 @Override
1489 public Map getNextOperationNameAndBatchId(int operationId, int taxonId) {
1490 return driver.getNextOperationNameAndBatchId(operationId, taxonId);
1491 }
1492
1493
1494
1495
1496
1497 @Override
1498 public BatchContainer<SpeciesBatch> getRootSpeciesBatch(Integer fishingOperationId, boolean validateTree) {
1499 return driver.getRootSpeciesBatch(fishingOperationId, validateTree);
1500 }
1501
1502 @Override
1503 public Set<Integer> getBatchChildIds(Integer id) {
1504 return driver.getBatchChildIds(id);
1505 }
1506
1507 @Override
1508 public SpeciesBatch createSpeciesBatch(SpeciesBatch bean, Integer parentBatchId, boolean computeRankOrder) {
1509 return driver.createSpeciesBatch(bean, parentBatchId, computeRankOrder);
1510 }
1511
1512 @Override
1513 public Collection<SpeciesBatch> createSpeciesBatches(Integer fishingOperationId, Collection<SpeciesBatch> beans) {
1514 return driver.createSpeciesBatches(fishingOperationId, beans);
1515 }
1516
1517 @Override
1518 public SpeciesBatch saveSpeciesBatch(SpeciesBatch bean) {
1519 return driver.saveSpeciesBatch(bean);
1520 }
1521
1522 @Override
1523 public void deleteSpeciesBatch(Integer id) {
1524 beforeDeleteBatch(id, true);
1525 driver.deleteSpeciesBatch(id);
1526 }
1527
1528 @Override
1529 public void deleteSpeciesSubBatch(Integer id) {
1530 beforeDeleteBatch(id, false);
1531 driver.deleteSpeciesSubBatch(id);
1532 }
1533
1534 @Override
1535 public void changeSpeciesBatchSpecies(Integer batchId, Species species) {
1536 driver.changeSpeciesBatchSpecies(batchId, species);
1537 }
1538
1539 @Override
1540 public List<SpeciesBatch> getAllSpeciesBatchToConfirm(Integer fishingOperationId) throws InvalidBatchModelException {
1541 return driver.getAllSpeciesBatchToConfirm(fishingOperationId);
1542 }
1543
1544 @Override
1545 public List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency(Integer speciesBatchId) {
1546 return driver.getAllSpeciesBatchFrequency(speciesBatchId);
1547 }
1548
1549 @Override
1550 public Multimap<Species, SpeciesBatchFrequency> getAllSpeciesBatchFrequencyForBatch(BatchContainer<SpeciesBatch> batchContainer) {
1551 return driver.getAllSpeciesBatchFrequencyForBatch(batchContainer);
1552 }
1553
1554 @Override
1555 public List<SpeciesBatchFrequency> saveSpeciesBatchFrequency(Integer speciesBatchId,
1556 List<SpeciesBatchFrequency> frequencies) {
1557 return driver.saveSpeciesBatchFrequency(speciesBatchId, frequencies);
1558 }
1559
1560
1561
1562
1563
1564 @Override
1565 public BatchContainer<SpeciesBatch> getRootBenthosBatch(Integer fishingOperationId, boolean validateTree) throws InvalidBatchModelException {
1566 return driver.getRootBenthosBatch(fishingOperationId, validateTree);
1567 }
1568
1569 @Override
1570 public SpeciesBatch createBenthosBatch(SpeciesBatch bean, Integer parentBatchId, boolean computeRankOrder) {
1571 return driver.createBenthosBatch(bean, parentBatchId, computeRankOrder);
1572 }
1573
1574 @Override
1575 public Collection<SpeciesBatch> createBenthosBatches(Integer fishingOperationId, Collection<SpeciesBatch> beans) {
1576 return driver.createBenthosBatches(fishingOperationId, beans);
1577 }
1578
1579 @Override
1580 public SpeciesBatch saveBenthosBatch(SpeciesBatch bean) {
1581 return driver.saveBenthosBatch(bean);
1582 }
1583
1584 @Override
1585 public void deleteBenthosBatch(Integer id) {
1586 beforeDeleteBatch(id, true);
1587 driver.deleteBenthosBatch(id);
1588 }
1589
1590 @Override
1591 public void deleteBenthosSubBatch(Integer id) {
1592 beforeDeleteBatch(id, false);
1593 driver.deleteBenthosSubBatch(id);
1594 }
1595
1596 @Override
1597 public void changeBenthosBatchSpecies(Integer batchId, Species species) {
1598 driver.changeBenthosBatchSpecies(batchId, species);
1599 }
1600
1601 @Override
1602 public List<SpeciesBatch> getAllBenthosBatchToConfirm(Integer fishingOperationId) throws InvalidBatchModelException {
1603 return driver.getAllBenthosBatchToConfirm(fishingOperationId);
1604 }
1605
1606 @Override
1607 public List<SpeciesBatchFrequency> getAllBenthosBatchFrequency(Integer benthosBatchId) {
1608 return driver.getAllBenthosBatchFrequency(benthosBatchId);
1609 }
1610
1611 @Override
1612 public Multimap<Species, SpeciesBatchFrequency> getAllBenthosBatchFrequencyForBatch(BatchContainer<SpeciesBatch> batchContainer) {
1613 return driver.getAllBenthosBatchFrequencyForBatch(batchContainer);
1614 }
1615
1616 @Override
1617 public List<SpeciesBatchFrequency> saveBenthosBatchFrequency(Integer benthosBatchId, List<SpeciesBatchFrequency> frequencies) {
1618 return driver.saveBenthosBatchFrequency(benthosBatchId, frequencies);
1619 }
1620
1621
1622
1623
1624
1625 @Override
1626 public BatchContainer<MarineLitterBatch> getRootMarineLitterBatch(Integer fishingOperationId) {
1627 return driver.getRootMarineLitterBatch(fishingOperationId);
1628 }
1629
1630 @Override
1631 public MarineLitterBatch createMarineLitterBatch(MarineLitterBatch bean) {
1632 return driver.createMarineLitterBatch(bean);
1633 }
1634
1635 @Override
1636 public Collection<MarineLitterBatch> createMarineLitterBatches(Integer fishingOperationId, Collection<MarineLitterBatch> beans) {
1637 return driver.createMarineLitterBatches(fishingOperationId, beans);
1638 }
1639
1640 @Override
1641 public MarineLitterBatch saveMarineLitterBatch(MarineLitterBatch bean) {
1642 return driver.saveMarineLitterBatch(bean);
1643 }
1644
1645 @Override
1646 public void deleteMarineLitterBatch(Integer id) {
1647 driver.deleteMarineLitterBatch(id);
1648 }
1649
1650
1651
1652
1653
1654 @Override
1655 public List<AccidentalBatch> getAllAccidentalBatch(Integer fishingOperationId) {
1656 return driver.getAllAccidentalBatch(fishingOperationId);
1657 }
1658
1659 @Override
1660 public Collection<AccidentalBatch> createAccidentalBatches(Collection<AccidentalBatch> beans) {
1661 return driver.createAccidentalBatches(beans);
1662 }
1663
1664 @Override
1665 public AccidentalBatch createAccidentalBatch(AccidentalBatch bean) {
1666 return driver.createAccidentalBatch(bean);
1667 }
1668
1669 @Override
1670 public AccidentalBatch saveAccidentalBatch(AccidentalBatch bean) {
1671 return driver.saveAccidentalBatch(bean);
1672 }
1673
1674 @Override
1675 public void deleteAccidentalBatch(String id) {
1676 driver.deleteAccidentalBatch(id);
1677 }
1678
1679 @Override
1680 public void deleteAccidentalBatchForFishingOperation(Integer fishingOperationId) {
1681 driver.deleteAccidentalBatchForFishingOperation(fishingOperationId);
1682 }
1683
1684
1685
1686
1687
1688 @Override
1689 public List<IndividualObservationBatch> getAllIndividualObservationBatchsForBatch(Integer batchId) {
1690 return driver.getAllIndividualObservationBatchsForBatch(batchId);
1691 }
1692
1693 @Override
1694 public List<IndividualObservationBatch> getAllIndividualObservationBatchsForFishingOperation(Integer fishingOperationId) {
1695 return driver.getAllIndividualObservationBatchsForFishingOperation(fishingOperationId);
1696 }
1697
1698 @Override
1699 public List<IndividualObservationBatch> getAllIndividualObservationBatchsForCruise(Integer cruiseId) {
1700 return driver.getAllIndividualObservationBatchsForCruise(cruiseId);
1701 }
1702
1703 @Override
1704 public boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix) {
1705 return driver.isSamplingCodeAvailable(cruiseId, referenceTaxonId, samplingCodeSuffix);
1706 }
1707
1708 @Override
1709 public List<IndividualObservationBatch> createIndividualObservationBatches(FishingOperation fishingOperation, Collection<IndividualObservationBatch> individualObservations) {
1710
1711 Optional<CruiseCache> optionalCruiseCache = getOptionalCruiseCache();
1712
1713 if (optionalCruiseCache.isPresent()) {
1714
1715
1716 CruiseCache cruiseCache = optionalCruiseCache.get();
1717
1718 List<IndividualObservationBatch> individualObservationsToRemove = getAllIndividualObservationBatchsForFishingOperation(fishingOperation.getIdAsInt());
1719
1720 if (log.isInfoEnabled()) {
1721 log.info("Remove from cruise sampling cache: " + fishingOperation + " with " + individualObservationsToRemove.size() + " individual observations.");
1722 }
1723 cruiseCache.removeFishingOperation(fishingOperation, individualObservationsToRemove);
1724
1725 }
1726
1727 List<IndividualObservationBatch> individualObservationBatches = driver.createIndividualObservationBatches(fishingOperation, individualObservations);
1728
1729 if (optionalCruiseCache.isPresent()) {
1730
1731
1732 CruiseCache cruiseCache = optionalCruiseCache.get();
1733
1734 List<IndividualObservationBatch> individualObservationsToAdd = getAllIndividualObservationBatchsForFishingOperation(fishingOperation.getIdAsInt());
1735 if (log.isInfoEnabled()) {
1736 log.info("Add to cruise sampling cache: " + fishingOperation + " with " + individualObservationsToAdd.size() + " individual observations.");
1737 }
1738 cruiseCache.addFishingOperation(fishingOperation, individualObservationsToAdd);
1739
1740 }
1741
1742 return individualObservationBatches;
1743 }
1744
1745 @Override
1746 public List<IndividualObservationBatch> saveBatchIndividualObservation(Integer batchId, List<IndividualObservationBatch> individualObservation) {
1747 return driver.saveBatchIndividualObservation(batchId, individualObservation);
1748 }
1749
1750 @Override
1751 public void deleteAllIndividualObservationsForFishingOperation(Integer fishingOperationId) {
1752 driver.deleteAllIndividualObservationsForFishingOperation(fishingOperationId);
1753 }
1754
1755 @Override
1756 public void deleteAllIndividualObservationsForBatch(Integer speciesBatchId) {
1757 driver.deleteAllIndividualObservationsForBatch(speciesBatchId);
1758 }
1759
1760 protected void beforeDeleteBatch(Integer id, boolean addBatchId) {
1761
1762 Optional<CruiseCache> optionalCruiseCache = getOptionalCruiseCache();
1763 if (optionalCruiseCache.isPresent()) {
1764
1765 CruiseCache cruiseCache = optionalCruiseCache.get();
1766
1767 FishingOperation fishingOperation = context.getDataContext().getFishingOperation();
1768
1769 Set<Integer> batchIds = new LinkedHashSet<>();
1770 if (addBatchId) {
1771 batchIds.add(id);
1772 }
1773 batchIds.addAll(getBatchChildIds(id));
1774
1775 batchIds.forEach(speciesBatchId -> {
1776
1777 List<IndividualObservationBatch> individualObservations = getAllIndividualObservationBatchsForBatch(speciesBatchId);
1778
1779 if (!individualObservations.isEmpty()) {
1780
1781 if (log.isInfoEnabled()) {
1782 log.info("Remove for species or benthos batch: " + speciesBatchId + " - " + individualObservations.size() + " individual observations from cruiseSamplingCache: " + cruiseCache);
1783 }
1784
1785 cruiseCache.removeIndividualObservations(fishingOperation, individualObservations);
1786
1787 }
1788
1789 });
1790
1791 }
1792
1793 }
1794
1795 private Optional<CruiseCache> getOptionalCruiseCache() {
1796 return context.getDataContext().getOptionalCruiseCache();
1797 }
1798
1799 }