View Javadoc
1   package fr.ifremer.tutti.service.genericformat;
2   
3   /*
4    * #%L
5    * Tutti :: Service
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import com.google.common.base.Preconditions;
28  import com.google.common.collect.ImmutableSet;
29  import fr.ifremer.tutti.persistence.ProgressionModel;
30  import fr.ifremer.tutti.persistence.entities.data.Cruise;
31  import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
32  import fr.ifremer.tutti.persistence.entities.data.Program;
33  import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol;
34  import fr.ifremer.tutti.persistence.model.ProgramDataModel;
35  import fr.ifremer.tutti.persistence.service.util.SynchronizationStatusHelper;
36  import fr.ifremer.tutti.service.AbstractTuttiService;
37  import fr.ifremer.tutti.service.DecoratorService;
38  import fr.ifremer.tutti.service.PdfGeneratorService;
39  import fr.ifremer.tutti.service.PersistenceService;
40  import fr.ifremer.tutti.service.TuttiServiceContext;
41  import fr.ifremer.tutti.service.catches.WeightCleaningService;
42  import fr.ifremer.tutti.service.genericformat.importactions.DoCheckWeightAction;
43  import fr.ifremer.tutti.service.genericformat.importactions.DoCleanWeightAction;
44  import fr.ifremer.tutti.service.genericformat.importactions.ImportAccidentalCatchAction;
45  import fr.ifremer.tutti.service.genericformat.importactions.ImportActionSupport;
46  import fr.ifremer.tutti.service.genericformat.importactions.ImportCatchAction;
47  import fr.ifremer.tutti.service.genericformat.importactions.ImportGearCaracteristicAction;
48  import fr.ifremer.tutti.service.genericformat.importactions.ImportIndividualObservationAction;
49  import fr.ifremer.tutti.service.genericformat.importactions.ImportMarineLitterAction;
50  import fr.ifremer.tutti.service.genericformat.importactions.ImportOperationAction;
51  import fr.ifremer.tutti.service.genericformat.importactions.ImportParameterAction;
52  import fr.ifremer.tutti.service.genericformat.importactions.ImportProtocolAction;
53  import fr.ifremer.tutti.service.genericformat.importactions.ImportReferentialGearAction;
54  import fr.ifremer.tutti.service.genericformat.importactions.ImportReferentialPersonAction;
55  import fr.ifremer.tutti.service.genericformat.importactions.ImportReferentialSpeciesAction;
56  import fr.ifremer.tutti.service.genericformat.importactions.ImportReferentialVesselAction;
57  import fr.ifremer.tutti.service.genericformat.importactions.ImportSurveyAction;
58  import fr.ifremer.tutti.service.genericformat.importactions.ImpotSampleCategoryAction;
59  import fr.ifremer.tutti.service.genericformat.importactions.LoadAttachmentsAction;
60  import fr.ifremer.tutti.service.genericformat.importactions.ValidateAccidentalCatchAction;
61  import fr.ifremer.tutti.service.genericformat.importactions.ValidateCatchAction;
62  import fr.ifremer.tutti.service.genericformat.importactions.ValidateGearCaracteristicAction;
63  import fr.ifremer.tutti.service.genericformat.importactions.ValidateIndividualObservationAction;
64  import fr.ifremer.tutti.service.genericformat.importactions.ValidateMarineLitterAction;
65  import fr.ifremer.tutti.service.genericformat.importactions.ValidateOperationAction;
66  import fr.ifremer.tutti.service.genericformat.importactions.ValidateParameterAction;
67  import fr.ifremer.tutti.service.genericformat.importactions.ValidateSurveyAction;
68  import org.apache.commons.logging.Log;
69  import org.apache.commons.logging.LogFactory;
70  import org.nuiton.decorator.Decorator;
71  
72  import java.io.File;
73  import java.util.LinkedHashSet;
74  import java.util.Set;
75  import java.util.stream.Collectors;
76  
77  import static org.nuiton.i18n.I18n.t;
78  
79  /**
80   * Created on 2/11/15.
81   *
82   * @author Tony Chemit - chemit@codelutin.com
83   * @since 3.14
84   */
85  public class GenericFormatImportService extends AbstractTuttiService {
86  
87      private static final Log log = LogFactory.getLog(GenericFormatImportService.class);
88  
89      private PersistenceService persistenceService;
90  
91      private PdfGeneratorService pdfGeneratorService;
92  
93      private Decorator<FishingOperation> fishingOperationDecorator;
94  
95      private Decorator<Cruise> cruiseDecorator;
96  
97      @Override
98      public void setServiceContext(TuttiServiceContext context) {
99  
100         super.setServiceContext(context);
101 
102         pdfGeneratorService = getService(PdfGeneratorService.class);
103         persistenceService = getService(PersistenceService.class);
104 
105         DecoratorService decoratorService = getService(DecoratorService.class);
106         cruiseDecorator = decoratorService.getDecoratorByType(Cruise.class);
107         fishingOperationDecorator = decoratorService.getDecoratorByType(FishingOperation.class);
108 
109     }
110 
111     public int getValidateImportFileNbSteps(GenericFormatImportConfiguration importConfiguration) {
112 
113         Preconditions.checkNotNull(importConfiguration);
114 
115         GenericFormatArchive archive = createArchive(importConfiguration);
116 
117         return 6   // check sampleCategoryModel + import ( gear + person + species + vessel + protocol )
118                      + archive.getSurveyLineCount() // load cruises
119                      + archive.getGearCaracteristicsPathLineCount()// load gear caracteristics
120                      + archive.getOperationPathLineCount() // load operations
121                      + archive.getParameterPathLineCount()// load parameters
122                      + archive.getCatchPathLineCount()// load catches
123                      + archive.getMarineLitterPathLineCount()// load marine litters
124                      + archive.getIndividualObservationPathLineCount()// load individualObservations
125                      + archive.getAccidentalCatchPathLineCount();
126 
127     }
128 
129     public GenericFormatValidateFileResult validateImportFile(GenericFormatImportConfiguration importConfiguration, ProgressionModel progressionModel) throws GenericFormatArchiveInvalidLayoutException {
130 
131         Preconditions.checkNotNull(importConfiguration);
132 
133         Preconditions.checkNotNull(progressionModel);
134 
135         GenericFormatArchive archive = createArchive(importConfiguration);
136 
137         GenericFormatImportRequest importRequest = createImportRequest(importConfiguration, archive);
138 
139         GenericFormatValidateFileResult result = doValidate(importRequest, progressionModel);
140         generateValidateReport(result, progressionModel);
141         return result;
142 
143     }
144 
145     public int getImportProgramNbSteps(GenericFormatImportConfiguration importConfiguration) {
146 
147         //TODO Recompute exact nb steps used...
148         Preconditions.checkNotNull(importConfiguration);
149 
150         GenericFormatArchive archive = createArchive(importConfiguration);
151 
152         int nbCruises = archive.getSurveyLineCount();
153         if (log.isInfoEnabled()) {
154             log.info("Count " + nbCruises + " cruises to import.");
155         }
156         int nbOperations = archive.getOperationPathLineCount();
157         if (log.isInfoEnabled()) {
158             log.info("Count " + nbOperations + " operations to import.");
159         }
160 
161         boolean checkWeights = importConfiguration.isCheckWeights();
162         boolean cleanWeights = importConfiguration.isCleanWeights();
163 
164         return 6                      // check sampleCategoryModel + import ( gear + person + species + vessel + protocol )
165                      + 1 + nbCruises        // load cruises + nbCruise * persist cruise
166                      + 1 + nbCruises        // load gear caracteristics + nbCruise * persist gear caracteristics
167                      + 1 + nbOperations     // load operations + nbOperations * persist operation
168                      + 1 + nbOperations     // load parameters + nbOperations * persist parameters
169                      + 1 + nbOperations * 2 // load catches + nbOperations * persist (species batches + benthos batches)
170                      + 1 + nbOperations     // load marine litters + nbOperations * persist marine litters
171                      + 1 + nbOperations     // load individualObservations + nbOperations * persist individualObservations
172                      + 1 + nbOperations     // load accidental catches + nbOperations * persist accidental catches
173                      + (cleanWeights ? nbOperations : 0)         // nbOperations * cleanWeights
174                      + (checkWeights ? nbOperations : 0)         // nbOperations * checkWeights
175                      + 1;
176 
177     }
178 
179     public GenericFormatImportResult importProgram(GenericFormatImportConfiguration importConfiguration, ProgressionModel progressionModel) {
180 
181         Preconditions.checkNotNull(importConfiguration);
182 
183         Preconditions.checkNotNull(progressionModel);
184 
185         GenericFormatArchive archive = createArchive(importConfiguration);
186 
187         archive.validateArchiveLayout();
188 
189         GenericFormatImportRequest importRequest = createImportRequest(importConfiguration, archive);
190 
191         SynchronizationStatusHelper.doNotPropagateDirtyStatusToParents();
192 
193         try {
194 
195             GenericFormatImportResult result = doImport(importRequest, progressionModel);
196 
197             generateImportReport(result, progressionModel);
198 
199             return result;
200 
201         } finally {
202 
203             SynchronizationStatusHelper.propagateDirtyStatusToParents();
204 
205         }
206 
207     }
208 
209     protected void generateImportReport(GenericFormatImportResult result, ProgressionModel progressionModel) {
210 
211         File reportFile = result.getReportFile();
212 
213         progressionModel.increments(t("tutti.service.genericFormat.import.computeReport", reportFile));
214 
215         pdfGeneratorService.generatePdf(reportFile, context.getConfig().getI18nLocale(), "genericFormatImportReport.ftl", result);
216 
217     }
218 
219     protected void generateValidateReport(GenericFormatValidateFileResult result, ProgressionModel progressionModel) {
220 
221         File reportFile = result.getReportFile();
222 
223         progressionModel.increments(t("tutti.service.genericFormat.validate.computeReport"));
224 
225         pdfGeneratorService.generatePdf(reportFile, context.getConfig().getI18nLocale(), "genericFormatValidateReport.ftl", result);
226 
227     }
228 
229     protected void validateArchiveLayout(GenericFormatContextSupport importContext) {
230 
231         try {
232             importContext.getImportRequest().getArchive().validateArchiveLayout();
233         } catch (GenericFormatArchiveInvalidLayoutException e) {
234 
235             importContext.setArchiveLayoutErrors(e.getErrors());
236 
237         }
238 
239     }
240 
241     protected GenericFormatValidateFileResult doValidate(GenericFormatImportRequest request, ProgressionModel progressionModel) {
242 
243         try (GenericFormatValidateFileContext importContext = new GenericFormatValidateFileContext(request, progressionModel, persistenceService, cruiseDecorator, fishingOperationDecorator)) {
244 
245             validateArchiveLayout(importContext);
246 
247             if (importContext.isArchiveLayoutValid()) {
248 
249                 GenericformatImportPersistenceHelper persitenceHelper = new GenericformatImportPersistenceHelper(context, importContext);
250 
251                 Set<ImportActionSupport> actions = createValidateActions(importContext, persitenceHelper);
252 
253                 actions.forEach(ImportActionSupport::execute);
254 
255             }
256 
257             return new GenericFormatValidateFileResult(importContext);
258 
259         }
260 
261     }
262 
263     protected GenericFormatImportResult doImport(GenericFormatImportRequest request, ProgressionModel progressionModel) {
264 
265         try (GenericFormatImportContext importContext = new GenericFormatImportContext(request, progressionModel, persistenceService, cruiseDecorator, fishingOperationDecorator)) {
266 
267             validateArchiveLayout(importContext);
268 
269             if (importContext.isArchiveLayoutValid()) {
270 
271                 GenericformatImportPersistenceHelper persitenceHelper = new GenericformatImportPersistenceHelper(context, importContext);
272 
273                 Set<ImportActionSupport> actions = createImportActions(importContext, persitenceHelper);
274 
275                 actions.forEach(ImportActionSupport::execute);
276 
277             }
278 
279             return new GenericFormatImportResult(importContext);
280 
281         }
282 
283     }
284 
285     protected GenericFormatImportRequest createImportRequest(GenericFormatImportConfiguration importConfiguration, GenericFormatArchive archive) {
286 
287         ProgramDataModel dataToExport = importConfiguration.getDataToExport();
288         Preconditions.checkNotNull(dataToExport);
289 
290         String programId = dataToExport.getId();
291         Preconditions.checkNotNull(programId);
292 
293         Program program = persistenceService.getProgram(programId);
294         Preconditions.checkNotNull(program);
295 
296         if (log.isDebugEnabled()) {
297             log.debug("Will import into program: " + programId);
298         }
299 
300         // Full load cruise
301         Set<Cruise> cruises = persistenceService.getAllCruiseId(program.getId())
302                                                 .stream()
303                                                 .map(cruiseId -> persistenceService.getCruise(cruiseId))
304                                                 .collect(Collectors.toCollection(LinkedHashSet::new));
305 
306         TuttiProtocol protocol = persistenceService.getProtocol();
307 
308         ProgramDataModel dataModel = persistenceService.loadProgram(programId, true);
309         return new GenericFormatImportRequest(importConfiguration,
310                                               archive,
311                                               ';',
312                                               program,
313                                               context.getSampleCategoryModel(),
314                                               ImmutableSet.copyOf(cruises),
315                                               dataModel,
316                                               protocol);
317 
318     }
319 
320     protected GenericFormatArchive createArchive(GenericFormatImportConfiguration importConfiguration) {
321 
322         File importFile = importConfiguration.getImportFile();
323         Preconditions.checkNotNull(importFile);
324         Preconditions.checkState(importFile.exists());
325 
326         return GenericFormatArchive.forImport(importFile, context.getConfig().getTmpDirectory());
327 
328     }
329 
330     protected Set<ImportActionSupport> createValidateActions(GenericFormatValidateFileContext importContext, GenericformatImportPersistenceHelper persitenceHelper) {
331 
332         Set<ImportActionSupport> actions = new LinkedHashSet<>();
333         addTechnicalActions(importContext, actions, persitenceHelper);
334         actions.add(new LoadAttachmentsAction(importContext));
335         actions.add(new ValidateSurveyAction(importContext, persitenceHelper));
336         actions.add(new ValidateGearCaracteristicAction(importContext));
337         actions.add(new ValidateOperationAction(importContext));
338         actions.add(new ValidateParameterAction(importContext));
339         actions.add(new ValidateCatchAction(importContext));
340         actions.add(new ValidateMarineLitterAction(importContext));
341         actions.add(new ValidateAccidentalCatchAction(importContext));
342         actions.add(new ValidateIndividualObservationAction(importContext, persitenceHelper));
343         return actions;
344 
345     }
346 
347     protected Set<ImportActionSupport> createImportActions(GenericFormatImportContext importContext, GenericformatImportPersistenceHelper persitenceHelper) {
348 
349         Set<ImportActionSupport> actions = new LinkedHashSet<>();
350         addTechnicalActions(importContext, actions, persitenceHelper);
351         actions.add(new LoadAttachmentsAction(importContext));
352         actions.add(new ImportSurveyAction(importContext, persitenceHelper));
353         actions.add(new ImportGearCaracteristicAction(importContext, persitenceHelper));
354         actions.add(new ImportOperationAction(importContext, persitenceHelper));
355         actions.add(new ImportParameterAction(importContext, persitenceHelper));
356         actions.add(new ImportCatchAction(importContext, persitenceHelper));
357         actions.add(new ImportMarineLitterAction(importContext, persitenceHelper));
358         actions.add(new ImportAccidentalCatchAction(importContext, persitenceHelper));
359         actions.add(new ImportIndividualObservationAction(importContext, persitenceHelper));
360         actions.add(new DoCleanWeightAction(importContext, context.getService(WeightCleaningService.class)));
361         actions.add(new DoCheckWeightAction(importContext, context.getService(GenericFormatCheckDataService.class)));
362         return actions;
363 
364     }
365 
366     protected void addTechnicalActions(GenericFormatContextSupport importContext, Set<ImportActionSupport> actions, GenericformatImportPersistenceHelper persitenceHelper) {
367 
368         actions.add(new ImpotSampleCategoryAction(importContext, persitenceHelper));
369         actions.add(new ImportReferentialGearAction(importContext, persitenceHelper));
370         actions.add(new ImportReferentialPersonAction(importContext, persitenceHelper));
371         actions.add(new ImportReferentialSpeciesAction(importContext, persitenceHelper));
372         actions.add(new ImportReferentialVesselAction(importContext, persitenceHelper));
373         actions.add(new ImportProtocolAction(importContext, persitenceHelper));
374 
375     }
376 
377 }