View Javadoc
1   package fr.ifremer.tutti.service.report;
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.Lists;
29  import fr.ifremer.tutti.TuttiConfiguration;
30  import fr.ifremer.tutti.persistence.ProgressionModel;
31  import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
32  import fr.ifremer.tutti.persistence.model.ProgramDataModel;
33  import fr.ifremer.tutti.service.AbstractTuttiService;
34  import fr.ifremer.tutti.service.PersistenceService;
35  import fr.ifremer.tutti.service.genericformat.GenericFormatExportConfiguration;
36  import fr.ifremer.tutti.service.genericformat.GenericFormatExportResult;
37  import fr.ifremer.tutti.service.genericformat.GenericFormatExportService;
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.nuiton.jaxx.application.ApplicationTechnicalException;
41  
42  import java.io.File;
43  import java.io.FileFilter;
44  import java.io.IOException;
45  import java.util.ArrayList;
46  import java.util.Arrays;
47  import java.util.List;
48  
49  import static org.nuiton.i18n.I18n.t;
50  
51  /**
52   * Created on 3/11/15.
53   *
54   * @author Tony Chemit - chemit@codelutin.com
55   * @since 3.13.2
56   */
57  public class ReportGenerationService extends AbstractTuttiService {
58  
59      private static final Log log = LogFactory.getLog(ReportGenerationService.class);
60  
61      private static final FileFilter REPORT_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".rptdesign");
62  
63      public List<File> getAvailableReports() {
64          List<File> result = Lists.newArrayList();
65          File reportDirectory = context.getConfig().getReportDirectory();
66          File[] files = reportDirectory.listFiles(REPORT_FILTER);
67          if (files != null) {
68              result.addAll(Arrays.asList(files));
69          }
70          return result;
71      }
72  
73      public ReportGenerationResult generateReport(ReportGenerationRequest request, ProgressionModel progressionModel) {
74  
75          Preconditions.checkNotNull(request);
76          Preconditions.checkNotNull(request.getReport());
77          Preconditions.checkState(request.getReport().exists());
78          Preconditions.checkNotNull(request.getProgramId());
79          Preconditions.checkNotNull(request.getCruiseId());
80          Preconditions.checkNotNull(request.getFishingOperationId());
81  
82          // load fishing operation
83          progressionModel.increments(t("tutti.report.step.load.fishingOperation"));
84          FishingOperation operation = getService(PersistenceService.class).
85                  getFishingOperation(request.getFishingOperationId());
86  
87          // export fishing operation
88          progressionModel.increments(t("tutti.report.step.export.fishingOperation"));
89          GenericFormatExportService service = getService(GenericFormatExportService.class);
90          GenericFormatExportConfiguration exportConfiguration = createExportConfigurationForFishingOperation(request.getProgramId(), request.getCruiseId(), request.getFishingOperationId(), null);
91  
92          GenericFormatExportResult exportResult = service.export(exportConfiguration, progressionModel);
93  
94          File exportDirectory = exportResult.getArchive().getWorkingDirectoryPath();
95          
96          File outputFile = newOutputFile();
97  
98          ReportGenerationContext reportContext = new ReportGenerationContext(request,
99                                                                              operation,
100                                                                             exportDirectory,
101                                                                             outputFile);
102 
103         progressionModel.increments(t("tutti.report.step.generateReport", request.getReport().getName()));
104 
105         return generateReport(reportContext);
106 
107     }
108 
109     protected GenericFormatExportConfiguration createExportConfigurationForFishingOperation(String programId, Integer cruiseId, Integer fishingOperationId, File exportFile) {
110 
111         Preconditions.checkNotNull(programId);
112         Preconditions.checkNotNull(cruiseId);
113         Preconditions.checkNotNull(fishingOperationId);
114 
115         PersistenceService persistenceService = getService(PersistenceService.class);
116 
117         ProgramDataModel dataToExport = persistenceService.loadCruise(programId, cruiseId, fishingOperationId);
118 
119         GenericFormatExportConfiguration configuration = new GenericFormatExportConfiguration();
120         configuration.setExportFile(exportFile);
121         configuration.setExportAttachments(true);
122         configuration.setExportSpecies(true);
123         configuration.setExportBenthos(true);
124         configuration.setExportMarineLitter(true);
125         configuration.setExportAccidentalCatch(true);
126         configuration.setExportIndividualObservation(true);
127         configuration.setDataToExport(dataToExport);
128         return configuration;
129 
130     }
131 
132 
133     protected File newOutputFile() {
134         return context.getConfig().newTempFile("tutti-report", ".pdf");
135     }
136 
137     protected ReportGenerationResult generateReport(ReportGenerationContext reportContext) {
138 
139         Preconditions.checkNotNull(reportContext.getFishingOperation());
140         Preconditions.checkNotNull(reportContext.getExportDirectory());
141         Preconditions.checkState(reportContext.getExportDirectory().exists());
142 
143         if (log.isInfoEnabled()) {
144             log.info("Will generate report using report " + reportContext.getReport().getName());
145         }
146 
147         List<String> arguments = prepareCall(reportContext);
148 
149         ProcessBuilder pb = new ProcessBuilder(arguments);
150 
151         pb.inheritIO();
152 
153         if (log.isInfoEnabled()) {
154             log.info("Starts java command: " + arguments);
155         }
156 
157         try {
158 
159             int exitCode = pb.start().waitFor();
160 
161             if (log.isDebugEnabled()) {
162                 log.debug("Exit Code: " + exitCode);
163             }
164 
165             if (exitCode != 0) {
166                 throw new ApplicationTechnicalException("Report execution failed, see the report log directory " + context.getConfig().getReportLogDirectory());
167             }
168 
169         } catch (InterruptedException | IOException e) {
170             throw new ApplicationTechnicalException("Could not generate report", e);
171         }
172 
173         if (log.isInfoEnabled()) {
174             log.info("Report generated at: " + reportContext.getOutputFile());
175         }
176 
177         return reportContext.toResult();
178 
179     }
180 
181     protected List<String> prepareCall(ReportGenerationContext reportContext) {
182 
183         TuttiConfiguration config = context.getConfig();
184 
185         File reportJarPath = config.getReportJarPath();
186 
187         Preconditions.checkState(reportJarPath != null, "No reportJarPath configured!");
188 
189         List<String> command = new ArrayList<>();
190 
191         command.add(config.getJavaCommandPath());
192 
193         // jvm options
194         command.add("-XX:MaxPermSize=128M");
195         command.add("-XX:PermSize=64M");
196         command.add("-XX:MaxNewSize=32M");
197         command.add("-XX:NewSize=32M");
198         command.add("-Xms128m");
199         command.add("-Xmx512m");
200 
201         //command.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000");
202 
203         command.add("-jar");
204 
205         command.add(reportJarPath.getAbsolutePath());
206 
207         // arguments
208 
209         command.add(config.getReportHomeDirectory().getAbsolutePath());
210         command.add(config.getReportLogDirectory().getAbsolutePath());
211         command.add(reportContext.getReport().getAbsolutePath());
212         command.add(reportContext.getOutputFile().getAbsolutePath());
213         command.add(reportContext.getExportDirectory().getAbsolutePath());
214         command.add(reportContext.getFishingOperation().getStationNumber());
215         command.add(reportContext.getFishingOperation().getFishingOperationNumber().toString());
216 
217         return command;
218 
219     }
220 
221     public int getNbSteps(ReportGenerationRequest request) {
222 
223         // get data / export / generate
224         int result = 4;
225 
226         GenericFormatExportService service = getService(GenericFormatExportService.class);
227         GenericFormatExportConfiguration exportConfiguration = createExportConfigurationForFishingOperation(request.getProgramId(), request.getCruiseId(), request.getFishingOperationId(), null);
228         result += service.getExportNbSteps(exportConfiguration);
229         return result;
230 
231     }
232 
233 }