View Javadoc
1   package fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.multiedit;
2   
3   import com.google.common.collect.ImmutableList;
4   import fr.ifremer.dali.dto.DaliBeanFactory;
5   import fr.ifremer.dali.dto.DaliBeans;
6   import fr.ifremer.dali.dto.data.measurement.MeasurementDTO;
7   import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
8   import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
9   import fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedRowModel;
10  import fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedTableModel;
11  import fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedTableUI;
12  import fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.shared.AbstractOperationMeasurementsGroupedTableModel;
13  import fr.ifremer.dali.ui.swing.content.observation.operation.measurement.grouped.shared.AbstractOperationMeasurementsGroupedTableUIHandler;
14  import fr.ifremer.dali.ui.swing.util.table.DaliColumnIdentifier;
15  import fr.ifremer.dali.ui.swing.util.table.renderer.MultipleValueCellRenderer;
16  import fr.ifremer.quadrige3.core.dao.technical.Assert;
17  import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil;
18  import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
19  import fr.ifremer.quadrige3.ui.swing.table.state.FixedSwingTableSessionState;
20  import fr.ifremer.quadrige3.ui.swing.table.state.SwingTableSessionState;
21  import jaxx.runtime.swing.session.State;
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.jdesktop.swingx.table.TableColumnExt;
25  import org.nuiton.jaxx.application.swing.util.Cancelable;
26  
27  import javax.swing.table.TableColumn;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Objects;
31  
32  /**
33   * Controleur pour les mesures de l'observation.
34   */
35  public class OperationMeasurementsMultiEditUIHandler
36      extends AbstractOperationMeasurementsGroupedTableUIHandler<OperationMeasurementsGroupedRowModel, OperationMeasurementsMultiEditUIModel, OperationMeasurementsMultiEditUI>
37      implements Cancelable {
38  
39      private static final Log LOG = LogFactory.getLog(OperationMeasurementsMultiEditUIHandler.class);
40  
41      /**
42       * <p>Constructor for OperationMeasurementsMultiEditUIHandler.</p>
43       */
44      public OperationMeasurementsMultiEditUIHandler() {
45          super(
46              OperationMeasurementsGroupedRowModel.PROPERTY_TAXON_GROUP,
47              OperationMeasurementsGroupedRowModel.PROPERTY_TAXON,
48              OperationMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_PMFMS,
49              OperationMeasurementsGroupedRowModel.PROPERTY_COMMENT
50          );
51      }
52  
53      /**
54       * {@inheritDoc}
55       */
56      @Override
57      public AbstractOperationMeasurementsGroupedTableModel<OperationMeasurementsGroupedRowModel> getTableModel() {
58          return (OperationMeasurementsGroupedTableModel) getTable().getModel();
59      }
60  
61      @Override
62      protected OperationMeasurementsMultiEditUIModel createNewModel() {
63          return new OperationMeasurementsMultiEditUIModel();
64      }
65  
66      @Override
67      protected OperationMeasurementsGroupedRowModel createNewRow(boolean readOnly, SamplingOperationDTO parentBean) {
68          return new OperationMeasurementsGroupedRowModel(readOnly);
69      }
70  
71      /**
72       * {@inheritDoc}
73       */
74      @Override
75      public SwingTable getTable() {
76          return getUI().getOperationGroupedMeasurementMultiEditTable();
77      }
78  
79      /**
80       * Initialisation du tableau.
81       */
82      @Override
83      protected void initTable() {
84  
85          final TableColumnExt samplingCol = addFixedColumn(OperationMeasurementsGroupedTableModel.SAMPLING);
86          samplingCol.setEditable(false);
87  
88          // Colonne groupe taxon
89          addColumn(
90              taxonGroupCellEditor,
91              newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON_GROUP),
92              OperationMeasurementsGroupedTableModel.TAXON_GROUP);
93  
94          // Colonne taxon
95          addColumn(
96              taxonCellEditor,
97              newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON),
98              OperationMeasurementsGroupedTableModel.TAXON);
99  
100         // Colonne taxon saisi
101         final TableColumnExt colInputTaxon = addColumn(OperationMeasurementsGroupedTableModel.INPUT_TAXON_NAME);
102         colInputTaxon.setEditable(false);
103 
104         // Colonne analyste
105         addColumn(
106             departmentCellEditor,
107             newTableCellRender(AbstractOperationMeasurementsGroupedTableModel.ANALYST),
108             AbstractOperationMeasurementsGroupedTableModel.ANALYST);
109 
110         // No comment column because comment editor is also a JDialog
111 //        final TableColumnExt colComment = addCommentColumn(OperationMeasurementsGroupedTableModel.COMMENT);
112 
113         // Modele de la table
114         final OperationMeasurementsGroupedTableModel tableModel = new OperationMeasurementsGroupedTableModel(getTable().getColumnModel(), false);
115         tableModel.setNoneEditableCols();
116         getTable().setModel(tableModel);
117 
118         // Initialisation de la table
119         initTable(getTable());
120 
121         // border
122         addEditionPanelBorder();
123     }
124 
125     /**
126      * Don't really build rows but create a multi edit row
127      *
128      * @param readOnly readOnly
129      * @return rows from model
130      */
131     @Override
132     protected List<OperationMeasurementsGroupedRowModel> buildRows(boolean readOnly) {
133 
134         if (getModel().getRowsToEdit().isEmpty())
135             return null;
136 
137         // Create a ghost row without parent
138         OperationMeasurementsGroupedRowModel multiEditRow = createNewRow(readOnly, null);
139         multiEditRow.setIndividualPmfms(new ArrayList<>(getModel().getPmfms()));
140         DaliBeans.createEmptyMeasurements(multiEditRow);
141 
142         boolean firstRow = true;
143         for (OperationMeasurementsGroupedRowModel row : getModel().getRowsToEdit()) {
144 
145             // find multiple value on each known columns
146             findMultipleValueOnIdentifier(row, multiEditRow, firstRow);
147 
148             // find multiple value on each measurement
149             findMultipleValueOnPmfmIdentifier(row, multiEditRow, firstRow);
150 
151             firstRow = false;
152         }
153 
154         overrideColumnRenderersAndEditors(multiEditRow);
155 
156         overrideColumnWidthAndPosition();
157 
158         return ImmutableList.of(multiEditRow);
159     }
160 
161     // detect multiple values on each column
162     private void findMultipleValueOnIdentifier(OperationMeasurementsGroupedRowModel row, OperationMeasurementsGroupedRowModel multiEditRow, boolean firstRow) {
163 
164         for (DaliColumnIdentifier<OperationMeasurementsGroupedRowModel> identifier : getModel().getIdentifiersToCheck()) {
165             if (!multiEditRow.getMultipleValuesOnIdentifier().contains(identifier)) {
166                 if (!Objects.equals(identifier.getValue(row), identifier.getValue(multiEditRow))) {
167                     if (firstRow) {
168                         // on first row, consider a unique value
169                         identifier.setValue(multiEditRow, identifier.getValue(row));
170                     } else {
171                         // on other rows, if the value differs, set it as multiple
172                         identifier.setValue(multiEditRow, null);
173                         multiEditRow.addMultipleValuesOnIdentifier(identifier);
174                     }
175                 }
176             }
177         }
178     }
179 
180     // detect multiple values on each pmfm column
181     private void findMultipleValueOnPmfmIdentifier(OperationMeasurementsGroupedRowModel row, OperationMeasurementsGroupedRowModel multiEditRow, boolean firstRow) {
182 
183         for (PmfmDTO pmfm : getModel().getPmfms()) {
184             if (!multiEditRow.getMultipleValuesOnPmfmIds().contains(pmfm.getId())) {
185                 MeasurementDTO multiMeasurement = DaliBeans.getIndividualMeasurementByPmfmId(multiEditRow, pmfm.getId());
186                 Assert.notNull(multiMeasurement, "should be already present");
187                 MeasurementDTO measurement = DaliBeans.getIndividualMeasurementByPmfmId(row, pmfm.getId());
188                 if (measurement == null) {
189                     // create ghost measurement
190                     measurement = DaliBeanFactory.newMeasurementDTO();
191                     measurement.setPmfm(pmfm);
192                 }
193 
194                 if (!DaliBeans.measurementValuesEquals(multiMeasurement, measurement)) {
195                     if (firstRow) {
196                         // on first row, consider a unique value
197                         multiMeasurement.setNumericalValue(measurement.getNumericalValue());
198                         multiMeasurement.setQualitativeValue(measurement.getQualitativeValue());
199                     } else {
200                         // on other rows, if the value differs, set it as multiple
201                         multiMeasurement.setNumericalValue(null);
202                         multiMeasurement.setQualitativeValue(null);
203                         multiEditRow.addMultipleValuesOnPmfmId(pmfm.getId());
204                     }
205                 }
206             }
207         }
208     }
209 
210     /**
211      * Override all column renderers with specific behavior if multiple values is found
212      *
213      * @param multiEditRow
214      */
215     private void overrideColumnRenderersAndEditors(OperationMeasurementsGroupedRowModel multiEditRow) {
216 
217         multiEditRow.getMultipleValuesOnIdentifier().forEach(identifier -> {
218             TableColumn col = getTable().getColumnExt(identifier);
219             // override the renderer
220             col.setCellRenderer(new MultipleValueCellRenderer(col.getCellRenderer()));
221         });
222         multiEditRow.getMultipleValuesOnPmfmIds().forEach(pmfmId ->
223             getModel().getPmfmColumns().stream().filter(pmfmTableColumn -> pmfmTableColumn.getPmfmId() == pmfmId).findFirst()
224                 .ifPresent(pmfmTableColumn -> {
225                         // override the renderer
226                         pmfmTableColumn.setCellRenderer(new MultipleValueCellRenderer(pmfmTableColumn.getCellRenderer()));
227                         // and set not editable if the pmfm is set as read-only
228                         if (getModel().getReadOnlyPmfmIds().contains(pmfmId))
229                             pmfmTableColumn.setEditable(false);
230                     }
231                 ));
232     }
233 
234     private void overrideColumnWidthAndPosition() {
235 
236         OperationMeasurementsGroupedTableUI parentUI = ((OperationMeasurementsGroupedTableUI) ApplicationUIUtil.getParentUI(getUI()));
237         if (parentUI == null) {
238             LOG.warn("The parent of class 'OperationMeasurementsGroupedTableUI' should be found");
239             return;
240         }
241 
242         {
243             // get the state of the referent table
244             State referentState = getContext().getSwingSession().findStateByComponentName(".*" + parentUI.getHandler().getTable().getName());
245 
246             // apply this state to the current table
247             if (referentState instanceof SwingTableSessionState) {
248                 referentState.setState(getTable(), referentState);
249             }
250         }
251 
252         // get the state of the referent fixed table
253         if (getFixedTable() != null && parentUI.getHandler().getFixedTable() != null) {
254             State referentState = getContext().getSwingSession().findStateByComponentName(".*" + parentUI.getHandler().getFixedTable().getName());
255 
256             // apply this state to the current table
257             if (referentState instanceof FixedSwingTableSessionState) {
258                 referentState.setState(getFixedTable(), referentState);
259             }
260         }
261     }
262 
263     @Override
264     protected void onRowsAdded(List<OperationMeasurementsGroupedRowModel> addedRows) {
265         // Don't call super method because the row is already initialized in buildRows()
266 //        super.onRowsAdded(addedRows);
267     }
268 
269     @Override
270     protected void filterMeasurements() {
271     }
272 
273     public void valid() {
274         if (getModel().isValid()) {
275             closeDialog();
276         }
277     }
278 
279     @Override
280     public void cancel() {
281         stopListenValidatorValid(getValidator());
282         getModel().setValid(false);
283         closeDialog();
284     }
285 }