View Javadoc
1   package fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped;
2   
3   import com.google.common.collect.Multimap;
4   import fr.ifremer.dali.dto.DaliBeans;
5   import fr.ifremer.dali.dto.data.measurement.MeasurementDTO;
6   import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
7   import fr.ifremer.dali.dto.referential.DepartmentDTO;
8   import fr.ifremer.dali.service.DaliBusinessException;
9   import fr.ifremer.dali.service.DaliTechnicalException;
10  import fr.ifremer.dali.vo.PresetVO;
11  import fr.ifremer.quadrige3.core.dao.technical.factorization.Combination;
12  import fr.ifremer.quadrige3.core.dao.technical.factorization.CombinationList;
13  import fr.ifremer.quadrige3.core.dao.technical.factorization.MaxCombinationExceededException;
14  import fr.ifremer.quadrige3.core.exception.Exceptions;
15  import org.apache.commons.collections4.CollectionUtils;
16  import org.apache.commons.logging.Log;
17  import org.apache.commons.logging.LogFactory;
18  import org.nuiton.i18n.I18n;
19  
20  import javax.swing.SwingWorker;
21  import java.util.*;
22  import java.util.concurrent.ExecutionException;
23  
24  import static org.nuiton.i18n.I18n.t;
25  
26  /**
27   * @author peck7 on 03/07/2020.
28   */
29  class GridInitializer extends SwingWorker<Object, Void> {
30  
31      private final Log LOG = LogFactory.getLog(GridInitializer.class);
32      private final OperationMeasurementsGroupedTableUIHandler handler;
33      private final PresetVO preset;
34      private final List<OperationMeasurementsGroupedRowModel> rows;
35  
36      GridInitializer(OperationMeasurementsGroupedTableUIHandler handler, PresetVO preset) {
37          this.handler = handler;
38          this.preset = preset;
39          rows = new ArrayList<>();
40      }
41  
42      @Override
43      protected Object doInBackground() {
44  
45          if (LOG.isDebugEnabled()) {
46              // count all possible combinations
47              long count = 1;
48              for (Integer pmfmId : preset.getPmfmIds()) {
49                  count *= preset.getQualitativeValueIds(pmfmId).size();
50              }
51              LOG.debug("possible combinations = " + count);
52          }
53  
54          CombinationList combinations = handler.getContext().getRuleListService().buildAndFactorizeAllowedValues(
55              preset,
56              handler.getModel().getPreconditionRulesByPmfmIdMap(),
57              handler.getConfig().getGridInitializationMaxCombinationCount());
58  
59          // init the grid and values
60          List<SamplingOperationDTO> samplingOperations =
61              handler.getModel().getSamplingFilter() != null
62                  ? Collections.singletonList(handler.getModel().getSamplingFilter())
63                  : handler.getModel().getSamplingOperations();
64  
65          DepartmentDTO analyst = handler.getContext().getProgramStrategyService().getAnalysisDepartmentOfAppliedStrategyBySurvey(handler.getModel().getSurvey());
66  
67          Multimap<SamplingOperationDTO, OperationMeasurementsGroupedRowModel> existingRowsBySamplingOperation = DaliBeans.populateByProperty(
68              handler.getModel().getRows(),
69              OperationMeasurementsGroupedRowModel.PROPERTY_SAMPLING_OPERATION
70          );
71  
72          for (SamplingOperationDTO samplingOperation : samplingOperations) {
73              for (Combination combination : combinations) {
74  
75                  // Check presence of a row with this combination and skip it (Mantis #52403)
76                  if (isPresent(existingRowsBySamplingOperation.get(samplingOperation), combination))
77                      continue;
78  
79                  OperationMeasurementsGroupedRowModel row = handler.getTableModel().createNewRow();
80                  // Initialize the row
81                  row.setSamplingOperation(samplingOperation);
82                  row.setAnalyst(analyst);
83                  // Affect individual pmfms from parent model
84                  row.setIndividualPmfms(new ArrayList<>(handler.getModel().getPmfms()));
85                  // Create empty measurements
86                  DaliBeans.createEmptyMeasurements(row);
87                  // Get the measurements
88                  for (Map.Entry<Integer, Integer> entry : combination) {
89                      MeasurementDTO measurement = DaliBeans.getIndividualMeasurementByPmfmId(row, entry.getKey());
90                      if (measurement == null) {
91                          throw new DaliTechnicalException("No measurement found with id=" + entry.getKey());
92                      }
93                      // Set its qualitative value
94                      measurement.setQualitativeValue(
95                          DaliBeans.findById(measurement.getPmfm().getQualitativeValues(), entry.getValue())
96                      );
97                  }
98  
99                  // Add the line
100                 row.setValid(true);
101                 row.setInitialized(true); // Set this flag to prevent saving if not modified (Mantis #52658)
102                 rows.add(row);
103 
104             }
105             samplingOperation.setDirty(true);
106         }
107 
108         return null;
109     }
110 
111     /**
112      * Try to find in rows if the combination is already present
113      *
114      * @param rows        the rows to check
115      * @param combination the combination to find
116      * @return true if the combination is found
117      */
118     private boolean isPresent(Collection<OperationMeasurementsGroupedRowModel> rows, Combination combination) {
119         return rows.stream().anyMatch(row -> findCombination(row, combination));
120     }
121 
122     /**
123      * Check if the row already have this combination in its measurements
124      *
125      * @param row         the row the check
126      * @param combination the combination to find
127      * @return true if the combination is found
128      */
129     private boolean findCombination(OperationMeasurementsGroupedRowModel row, Combination combination) {
130         for (Map.Entry<Integer, Integer> entry : combination) {
131             MeasurementDTO measurement = DaliBeans.getIndividualMeasurementByPmfmId(row, entry.getKey());
132             if (measurement == null || measurement.getQualitativeValue() == null || !measurement.getQualitativeValue().getId().equals(entry.getValue()))
133                 // if this entry (pmfmId/qualitativeValuId) is not present in row's measurements, stop here
134                 return false;
135         }
136         return true;
137     }
138 
139     @Override
140     protected void done() {
141 
142         try {
143             Throwable resultException = null;
144             try {
145                 // get the result object
146                 Object result = get();
147                 // it can be an exception
148                 if (result instanceof Throwable) {
149                     resultException = (Throwable) result;
150                 }
151             } catch (InterruptedException | ExecutionException e) {
152                 resultException = e;
153             }
154 
155             // handle the exception
156             if (resultException != null) {
157                 if (Exceptions.hasCause(resultException, MaxCombinationExceededException.class)) {
158                     // show the MaxCombinationExceededException message
159                     handler.getContext().getDialogHelper().showErrorDialog(
160                         I18n.t("dali.samplingOperation.measurement.grouped.init.maxCombinationsExceeded", handler.getConfig().getGridInitializationMaxCombinationCount()),
161                         t("dali.samplingOperation.measurement.grouped.init.title"));
162                 } else if (Exceptions.hasCause(resultException, DaliBusinessException.class)) {
163                     // show the business message
164                     handler.getContext().getDialogHelper().showErrorDialog(
165                         Exceptions.getCause(resultException, DaliBusinessException.class).getMessage(),
166                         t("dali.samplingOperation.measurement.grouped.init.title"));
167                 } else {
168                     // show complete exception
169                     LOG.error(resultException.getMessage(), resultException);
170                     handler.getContext().getDialogHelper().showErrorDialog(
171                         resultException.getMessage(),
172                         t("dali.samplingOperation.measurement.grouped.init.title"));
173                 }
174                 return;
175             }
176 
177             if (LOG.isDebugEnabled()) LOG.debug("nb rows to add : " + rows.size());
178 
179             // show message if no tuple generated
180             if (CollectionUtils.isEmpty(rows)) {
181                 handler.getContext().getDialogHelper().showWarningDialog(
182                     t("dali.samplingOperation.measurement.grouped.init.empty"),
183                     t("dali.samplingOperation.measurement.grouped.init.title"));
184             } else {
185 
186                 // add rows
187                 handler.getModel().addRows(rows);
188                 handler.getModel().setModify(true);
189             }
190 
191         } finally {
192             handler.resetCellEditors();
193             handler.getModel().setLoading(false);
194         }
195     }
196 }