1 package fr.ifremer.reefdb.ui.swing.content.home.operation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import fr.ifremer.quadrige3.core.dao.technical.StringIterator;
27 import fr.ifremer.quadrige3.ui.swing.action.ActionFactory;
28 import fr.ifremer.quadrige3.ui.swing.component.coordinate.CoordinateEditor;
29 import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
30 import fr.ifremer.quadrige3.ui.swing.table.editor.ExtendedComboBoxCellEditor;
31 import fr.ifremer.quadrige3.ui.swing.table.editor.LocalTimeCellEditor;
32 import fr.ifremer.reefdb.decorator.DecoratorService;
33 import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
34 import fr.ifremer.reefdb.dto.ReefDbBeans;
35 import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
36 import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO;
37 import fr.ifremer.reefdb.dto.data.survey.SurveyDTO;
38 import fr.ifremer.reefdb.dto.enums.FilterTypeValues;
39 import fr.ifremer.reefdb.dto.referential.DepartmentDTO;
40 import fr.ifremer.reefdb.dto.referential.SamplingEquipmentDTO;
41 import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO;
42 import fr.ifremer.reefdb.service.ReefDbTechnicalException;
43 import fr.ifremer.reefdb.service.StatusFilter;
44 import fr.ifremer.reefdb.ui.swing.content.home.HomeUI;
45 import fr.ifremer.reefdb.ui.swing.content.home.operation.add.AddOperationTableUI;
46 import fr.ifremer.reefdb.ui.swing.content.home.survey.SurveysTableRowModel;
47 import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbBeanUIModel;
48 import fr.ifremer.reefdb.ui.swing.util.ReefDbUI;
49 import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler;
50 import jaxx.runtime.SwingUtil;
51 import org.apache.commons.collections4.CollectionUtils;
52 import org.apache.commons.lang3.StringUtils;
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55 import org.jdesktop.swingx.table.TableColumnExt;
56
57 import javax.swing.BorderFactory;
58 import javax.swing.SortOrder;
59 import javax.swing.SwingWorker;
60 import java.awt.Dimension;
61 import java.util.List;
62 import java.util.Optional;
63 import java.util.concurrent.ExecutionException;
64 import java.util.concurrent.ThreadPoolExecutor;
65
66 import static org.nuiton.i18n.I18n.t;
67
68
69
70
71 public class OperationsTableUIHandler extends AbstractReefDbTableUIHandler<OperationsTableRowModel, OperationsTableUIModel, OperationsTableUI> {
72
73
74
75
76 private static final Log LOG = LogFactory.getLog(OperationsTableUIHandler.class);
77 private ThreadPoolExecutor executor;
78 private ExtendedComboBoxCellEditor<SamplingEquipmentDTO> samplingEquipmentCellEditor;
79 private ExtendedComboBoxCellEditor<DepartmentDTO> samplingDepartmentCellEditor;
80 private ExtendedComboBoxCellEditor<DepartmentDTO> analystDepartmentCellEditor;
81
82
83
84
85 @Override
86 public OperationsTableModel getTableModel() {
87 return (OperationsTableModel) getTable().getModel();
88 }
89
90
91
92
93 @Override
94 public SwingTable getTable() {
95 return getUI().getOperationTable();
96 }
97
98
99
100
101 @Override
102 public void beforeInit(final OperationsTableUI ui) {
103 super.beforeInit(ui);
104
105
106 final OperationsTableUIModel model = new OperationsTableUIModel();
107 ui.setContextValue(model);
108 }
109
110
111
112
113 @Override
114 public void afterInit(OperationsTableUI ui) {
115
116
117 initUI(ui);
118
119 createSamplingDepartmentCellEditor();
120 createAnalystDepartmentCellEditor();
121 createSamplingEquipmentCellEditor();
122
123 iniTable();
124 SwingUtil.setLayerUI(ui.getHomePrelevementsScrollPane(), ui.getTableBlockLayer());
125
126
127 initListeners();
128
129
130 initActionComboBox(getUI().getPrelevementsPanelEditerCombobox());
131
132 ui.applyDataBinding(OperationsTableUI.BINDING_PRELEVEMENTS_PANEL_DUPLIQUER_BOUTON_ENABLED);
133 ui.applyDataBinding(OperationsTableUI.BINDING_PRELEVEMENTS_PANEL_EDITER_COMBOBOX_ENABLED);
134 ui.applyDataBinding(OperationsTableUI.BINDING_PRELEVEMENTS_PANEL_SUPPRIMER_BOUTON_ENABLED);
135
136
137 getUI().getNextButton().setBorder(
138 BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, getConfig().getColorHighlightButtonBorder()), ui.getNextButton().getBorder())
139 );
140
141 executor = ActionFactory.createSingleThreadExecutor(ActionFactory.ExecutionMode.LATEST);
142
143 }
144
145 @Override
146 public void onCloseUI() {
147 executor.shutdownNow();
148 super.onCloseUI();
149 }
150
151
152
153
154 @Override
155 protected String[] getRowPropertiesToIgnore() {
156 return new String[]{
157 OperationsTableRowModel.PROPERTY_ERRORS,
158 OperationsTableRowModel.PROPERTY_DIRTY,
159 OperationsTableRowModel.PROPERTY_MEASUREMENTS_LOADED
160 };
161 }
162
163
164
165
166 @Override
167 protected boolean isRowValid(final OperationsTableRowModel row) {
168 return (!row.isEditable() || super.isRowValid(row)) & isOperationValid(row);
169 }
170
171 private boolean isOperationValid(OperationsTableRowModel row) {
172
173
174 if (getModel().getRowCount() >= 2) {
175 for (OperationsTableRowModel otherRow : getModel().getRows()) {
176 if (row == otherRow) continue;
177 if (StringUtils.isNotBlank(row.getName()) && row.getName().equals(otherRow.getName())) {
178
179 ReefDbBeans.addError(row, t("reefdb.validator.error.samplingOperation.mnemonic.duplicate"), OperationsTableRowModel.PROPERTY_NAME);
180 }
181 }
182 }
183
184
185 if (row.getLatitude() == null ^ row.getLongitude() == null) {
186 ReefDbBeans.addError(row, t("reefdb.validator.error.coordinate.invalid"), OperationsTableRowModel.PROPERTY_LONGITUDE, OperationsTableRowModel.PROPERTY_LATITUDE);
187 }
188
189
190 if (row.getLatitude() != null && row.getLongitude() != null && row.getPositioning() == null) {
191 ReefDbBeans.addError(row, t("reefdb.validator.error.positioning.required"), OperationsTableRowModel.PROPERTY_POSITIONING);
192 }
193
194
195 if (row.getAnalyst() == null && row.getMeasurements().stream().anyMatch(measurement -> !ReefDbBeans.isMeasurementEmpty(measurement))) {
196 ReefDbBeans.addError(row, t("reefdb.validator.error.analyst.required"), OperationsTableRowModel.PROPERTY_ANALYST);
197 }
198
199
200 if (row.getSize() != null && row.getSizeUnit() == null) {
201 ReefDbBeans.addError(row, t("reefdb.validator.error.sizeUnit.required"), OperationsTableRowModel.PROPERTY_SIZE_UNIT);
202 }
203
204 boolean hasNoError = ReefDbBeans.hasNoBlockingError(row);
205
206 if (!hasNoError) {
207 ensureColumnsWithErrorAreVisible(row);
208 }
209
210 return hasNoError;
211 }
212
213
214
215
216 private void initListeners() {
217
218
219 getModel().addPropertyChangeListener(evt -> {
220
221 if (OperationsTableUIModel.PROPERTY_SINGLE_ROW_SELECTED.equals(evt.getPropertyName())) {
222
223 final SamplingOperationDTO prelevement = getModel().getSingleSelectedRow();
224 if (prelevement != null) {
225
226 updateSamplingDepartmentCellEditor(false);
227 updateAnalystDepartmentCellEditor(false);
228 updateSamplingEquipmentCellEditor(false);
229
230
231 getContext().setSelectedSamplingOperationId(getModel().getSingleSelectedRow().getId());
232 }
233
234 } else if (OperationsTableUIModel.PROPERTY_SURVEY_EDITABLE.equals(evt.getPropertyName())) {
235
236
237 getTableModel().setReadOnly(!getModel().isSurveyEditable());
238 }
239 });
240 }
241
242
243
244
245
246
247 public void loadOperations(final SurveysTableRowModel survey) {
248
249
250 if (getTable().isEditing()) {
251 getTable().getCellEditor().stopCellEditing();
252 }
253
254
255 saveTableState();
256
257
258 getModel().setSurvey(survey);
259
260 getModel().setLoading(true);
261 executor.execute(new SamplingOperationsLoader(survey));
262
263 }
264
265
266
267
268 private void iniTable() {
269
270
271 final TableColumnExt colName = addColumn(OperationsTableModel.NAME);
272 colName.setSortable(true);
273 colName.setMinWidth(100);
274
275
276 final TableColumnExt colSamplingEquipment = addColumn(
277 samplingEquipmentCellEditor,
278 newTableCellRender(OperationsTableModel.SAMPLING_EQUIPMENT),
279 OperationsTableModel.SAMPLING_EQUIPMENT
280 );
281 colSamplingEquipment.setSortable(true);
282 colSamplingEquipment.setMinWidth(100);
283
284
285 final TableColumnExt colTime = addColumn(
286 new LocalTimeCellEditor(),
287 newTableCellRender(Integer.class, DecoratorService.TIME_IN_HOURS_MINUTES),
288 OperationsTableModel.TIME);
289 colTime.setSortable(true);
290 colTime.setMinWidth(50);
291
292
293 addCommentColumn(OperationsTableModel.COMMENT);
294
295
296
297
298 final TableColumnExt colSize = addColumn(
299 newNumberCellEditor(Double.class, false, ReefDbUI.DECIMAL7_PATTERN),
300 newNumberCellRenderer(7),
301 OperationsTableModel.SIZE);
302 colSize.setSortable(true);
303 colSize.setMinWidth(50);
304
305
306 final TableColumnExt colSizeUnit = addExtendedComboDataColumnToModel(
307 OperationsTableModel.SIZE_UNIT,
308 getContext().getReferentialService().getUnits(StatusFilter.ACTIVE),
309 false);
310 colSizeUnit.setSortable(true);
311 colSizeUnit.setMinWidth(100);
312
313
314 final TableColumnExt colSamplingDepartment = addColumn(
315 samplingDepartmentCellEditor,
316 newTableCellRender(OperationsTableModel.SAMPLING_DEPARTMENT),
317 OperationsTableModel.SAMPLING_DEPARTMENT
318 );
319 colSamplingDepartment.setSortable(true);
320 colSamplingDepartment.setMinWidth(100);
321
322
323 final TableColumnExt colDepth = addColumn(
324 newNumberCellEditor(Double.class, false, ReefDbUI.DECIMAL2_PATTERN),
325 newNumberCellRenderer(2),
326 OperationsTableModel.DEPTH);
327 colDepth.setSortable(true);
328 colDepth.setMinWidth(100);
329
330
331 final TableColumnExt colMinDepth = addColumn(
332 newNumberCellEditor(Double.class, false, ReefDbUI.DECIMAL2_PATTERN),
333 newNumberCellRenderer(2),
334 OperationsTableModel.MIN_DEPTH);
335 colMinDepth.setSortable(true);
336 colMinDepth.setMinWidth(100);
337
338
339 final TableColumnExt colMaxDepth = addColumn(
340 newNumberCellEditor(Double.class, false, ReefDbUI.DECIMAL2_PATTERN),
341 newNumberCellRenderer(2),
342 OperationsTableModel.MAX_DEPTH);
343 colMaxDepth.setSortable(true);
344 colMaxDepth.setMinWidth(100);
345
346
347 final TableColumnExt colLatitude = addCoordinateColumnToModel(
348 CoordinateEditor.CoordinateType.LATITUDE_MIN,
349 OperationsTableModel.LATITUDE);
350 colLatitude.setSortable(true);
351 colLatitude.setMinWidth(100);
352
353 final TableColumnExt colLongitude = addCoordinateColumnToModel(
354 CoordinateEditor.CoordinateType.LONGITUDE_MIN,
355 OperationsTableModel.LONGITUDE);
356 colLongitude.setSortable(true);
357 colLongitude.setMinWidth(100);
358
359
360 final TableColumnExt colPositioning = addExtendedComboDataColumnToModel(
361 OperationsTableModel.POSITIONING,
362 getContext().getReferentialService().getPositioningSystems(),
363 false);
364 colPositioning.setSortable(true);
365 colPositioning.setMinWidth(100);
366
367 final TableColumnExt colPositioningPrecision = addColumn(
368 OperationsTableModel.POSITIONING_PRECISION);
369 colPositioningPrecision.setSortable(true);
370 colPositioningPrecision.setMinWidth(100);
371 colPositioningPrecision.setEditable(false);
372
373
374 final TableColumnExt colAnalystDepartment = addColumn(
375 analystDepartmentCellEditor,
376 newTableCellRender(OperationsTableModel.ANALYST),
377 OperationsTableModel.ANALYST
378 );
379 colAnalystDepartment.setSortable(true);
380 colAnalystDepartment.setMinWidth(100);
381
382
383 final OperationsTableModel tableModel = new OperationsTableModel(getTable().getColumnModel(), true);
384 getTable().setModel(tableModel);
385
386
387 initTable(getTable());
388
389
390 colSize.setVisible(false);
391 colSizeUnit.setVisible(false);
392 colSamplingDepartment.setVisible(false);
393
394 colDepth.setVisible(false);
395 colMinDepth.setVisible(false);
396 colMaxDepth.setVisible(false);
397 colLatitude.setVisible(false);
398 colLongitude.setVisible(false);
399 colPositioning.setVisible(false);
400 colPositioningPrecision.setVisible(false);
401
402
403 getTable().setSortOrder(OperationsTableModel.NAME, SortOrder.ASCENDING);
404
405
406 addEditionPanelBorder();
407 }
408
409 private void createSamplingEquipmentCellEditor() {
410
411 samplingEquipmentCellEditor = newExtendedComboBoxCellEditor(null, SamplingEquipmentDTO.class, false);
412
413 samplingEquipmentCellEditor.setAction("unfilter", "reefdb.common.unfilter", e -> {
414 if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
415 return;
416 }
417
418 updateSamplingEquipmentCellEditor(true);
419 getTable().requestFocus();
420 });
421
422 }
423
424 private void updateSamplingEquipmentCellEditor(boolean forceNoFilter) {
425
426 samplingEquipmentCellEditor.getCombo().setActionEnabled(!forceNoFilter
427 && getContext().getDataContext().isContextFiltered(FilterTypeValues.SAMPLING_EQUIPMENT));
428
429 samplingEquipmentCellEditor.getCombo().setData(
430 getContext().getObservationService().getAvailableSamplingEquipments(forceNoFilter));
431 }
432
433 private void createSamplingDepartmentCellEditor() {
434
435 samplingDepartmentCellEditor = newExtendedComboBoxCellEditor(null, DepartmentDTO.class, false);
436
437 samplingDepartmentCellEditor.setAction("unfilter", "reefdb.common.unfilter", e -> {
438 if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
439 return;
440 }
441
442 updateSamplingDepartmentCellEditor(true);
443 getTable().requestFocus();
444 });
445
446 }
447
448 private void updateSamplingDepartmentCellEditor(boolean forceNoFilter) {
449
450 samplingDepartmentCellEditor.getCombo().setActionEnabled(!forceNoFilter
451 && getContext().getDataContext().isContextFiltered(FilterTypeValues.DEPARTMENT));
452
453 samplingDepartmentCellEditor.getCombo().setData(
454 getContext().getObservationService().getAvailableDepartments(forceNoFilter));
455 }
456
457 private void createAnalystDepartmentCellEditor() {
458
459 analystDepartmentCellEditor = newExtendedComboBoxCellEditor(null, DepartmentDTO.class, false);
460
461 analystDepartmentCellEditor.setAction("unfilter", "reefdb.common.unfilter", e -> {
462 if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) {
463 return;
464 }
465
466 updateAnalystDepartmentCellEditor(true);
467 getTable().requestFocus();
468 });
469
470 }
471
472 private void updateAnalystDepartmentCellEditor(boolean forceNoFilter) {
473
474 analystDepartmentCellEditor.getCombo().setActionEnabled(!forceNoFilter
475 && getContext().getDataContext().isContextFiltered(FilterTypeValues.DEPARTMENT));
476
477 analystDepartmentCellEditor.getCombo().setData(
478 getContext().getObservationService().getAvailableDepartments(forceNoFilter));
479 }
480
481
482
483
484 @Override
485 protected void onRowModified(int rowIndex, OperationsTableRowModel row, String propertyName, Integer propertyIndex, Object oldValue, Object newValue) {
486 super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue);
487
488 row.setDirty(true);
489
490 if (OperationsTableRowModel.PROPERTY_NAME.equals(propertyName)) {
491 recomputeRowsValidState();
492
493 } else if (OperationsTableRowModel.PROPERTY_PMFMS.equals(propertyName)) {
494
495
496 row.setMeasurementsLoaded(true);
497
498 }
499
500 saveToSurvey();
501 }
502
503
504
505
506 public void addSamplingOperations() {
507
508 AddOperationTableUI dialog = new AddOperationTableUI(getContext());
509 dialog.getHandler().load(getModel());
510 openDialog(dialog, new Dimension(1000, 232));
511
512
513 List<OperationsTableRowModel> newOperations = dialog.getModel().getRows();
514 if (dialog.getModel().isValid() && CollectionUtils.isNotEmpty(newOperations)) {
515
516
517 String labelPrefix = dialog.getModel().getOperationNamePrefix();
518 StringIterator labelIterator = StringIterator.newStringIteratorByProperty(getModel().getRows(), SamplingOperationDTO.PROPERTY_NAME, labelPrefix);
519 newOperations.forEach(newOperation -> newOperation.setName(labelIterator.next()));
520
521 getModel().addRows(newOperations);
522 getModel().setModify(true);
523
524 recomputeRowsValidState();
525 saveToSurvey();
526
527
528 for (OperationsTableRowModel row : getModel().getRows()) {
529 if (StringUtils.isBlank(row.getName())) {
530 getTable().setTerminateEditOnFocusLost(false);
531 setFocusOnCell(row);
532 break;
533 }
534 }
535 }
536
537 }
538
539
540
541
542 public void removeSamplingOperations() {
543
544 if (getModel().getSelectedRows().isEmpty()) {
545 LOG.warn("Aucun prelevement de selectionne");
546 return;
547 }
548
549
550 boolean canContinue = askBeforeDelete(t("reefdb.action.delete.samplingOperation.title"), t("reefdb.action.delete.samplingOperation.message"));
551
552 if (canContinue) {
553
554
555 boolean hasMeasurement = false;
556 for (OperationsTableRowModel row : getModel().getSelectedRows()) {
557
558 if (!row.isMeasurementsEmpty()) {
559 for (MeasurementDTO measurement : row.getMeasurements()) {
560 if (measurement.getQualitativeValue() != null || measurement.getNumericalValue() != null) {
561 hasMeasurement = true;
562 break;
563 }
564 }
565 }
566 }
567
568 if (hasMeasurement) {
569 canContinue = askBeforeDelete(t("reefdb.action.delete.samplingOperation.measurement.title"), t("reefdb.action.delete.samplingOperation.measurement.message"));
570 }
571 }
572
573 if (canContinue) {
574
575
576 getModel().deleteSelectedRows();
577
578
579 recomputeRowsValidState();
580
581 forceRevalidateModel();
582
583 saveToSurvey();
584 }
585 }
586
587
588
589
590 private void saveToSurvey() {
591
592
593 for (OperationsTableRowModel rowModel : getModel().getRows()) {
594 if (!rowModel.isMeasurementsEmpty()) {
595 rowModel.getMeasurements().forEach(measurement -> measurement.setAnalyst(rowModel.getAnalyst()));
596 }
597 }
598
599
600 getModel().getSurvey().setSamplingOperations(getModel().getBeans());
601 getModel().getSurvey().setSamplingOperationsLoaded(true);
602
603
604 getModel().firePropertyChanged(AbstractReefDbBeanUIModel.PROPERTY_MODIFY, null, true);
605 }
606
607
608
609
610 @Override
611 protected void onRowsAdded(List<OperationsTableRowModel> addedRows) {
612 super.onRowsAdded(addedRows);
613
614 if (addedRows.size() == 1) {
615 OperationsTableRowModel rowModel = addedRows.get(0);
616
617 rowModel.setDirty(true);
618
619
620 if (StringUtils.isBlank(rowModel.getName())) {
621 rowModel.setName(StringIterator.newStringIteratorByProperty(getModel().getRows(), SamplingOperationDTO.PROPERTY_NAME).next());
622 }
623
624
625 if (rowModel.getSamplingDepartment() == null) {
626 rowModel.setSamplingDepartment(getModel().getSurvey().getRecorderDepartment());
627 }
628
629
630 rowModel.addAllPmfms(getModel().getPmfms());
631 for (PmfmDTO pmfm : getModel().getPmfms()) {
632 MeasurementDTO measurement = ReefDbBeanFactory.newMeasurementDTO();
633 measurement.setPmfm(pmfm);
634 rowModel.addMeasurements(measurement);
635 }
636
637
638 if (rowModel.getAnalyst() == null) {
639 rowModel.setAnalyst(
640 getContext().getProgramStrategyService().getAnalysisDepartmentOfAppliedStrategyBySurvey(
641 getModel().getSurvey(),
642 rowModel.getPmfms()
643 ));
644 }
645
646 getModel().setModify(true);
647 setFocusOnCell(rowModel);
648 }
649 }
650
651
652
653
654 public void onNext() {
655
656 HomeUI homeUI = getUI().getParentContainer(HomeUI.class);
657
658 getContext().getActionEngine().runAction(homeUI.getSurveysTable().getObservationEditerGeneralBouton());
659 }
660
661 private class SamplingOperationsLoader extends SwingWorker<Object, Object> {
662
663 List<PmfmDTO> pmfms;
664 final SurveyDTO survey;
665
666 private SamplingOperationsLoader(SurveyDTO survey) {
667 this.survey = survey;
668 }
669
670 @Override
671 protected Object doInBackground() {
672
673 if (survey != null) {
674
675
676 if (!survey.isSamplingOperationsLoaded()) {
677 getContext().getObservationService().loadSamplingOperationsFromSurvey(survey, false );
678 }
679
680
681 pmfms = getContext().getProgramStrategyService().getPmfmsForSamplingOperationBySurvey(survey);
682
683
684 if (!survey.isSamplingOperationsEmpty()) {
685
686 for (SamplingOperationDTO samplingOperation : survey.getSamplingOperations()) {
687 ReefDbBeans.fillListsEachOther(samplingOperation.getPmfms(), pmfms);
688 }
689 }
690 }
691
692 return null;
693 }
694
695 @Override
696 protected void done() {
697 try {
698 if (isCancelled()) {
699 return;
700 }
701 try {
702 get();
703 } catch (InterruptedException | ExecutionException e) {
704 throw new ReefDbTechnicalException(e.getMessage(), e);
705 }
706
707
708 getModel().setPmfms(pmfms);
709
710
711 addPmfmColumns(
712 getModel().getPmfms(),
713 SamplingOperationDTO.PROPERTY_PMFMS,
714 DecoratorService.NAME_WITH_UNIT,
715 OperationsTableModel.TIME);
716
717 boolean notEmpty = CollectionUtils.isNotEmpty(getModel().getPmfmColumns());
718
719 if (survey != null && !survey.isSamplingOperationsEmpty()) {
720
721 getModel().setBeans(survey.getSamplingOperations());
722
723 if (notEmpty) {
724 for (OperationsTableRowModel row : getModel().getRows()) {
725
726 Optional<MeasurementDTO> measurementFound = row.getMeasurements().stream().filter(measurement -> measurement.getAnalyst() != null).findFirst();
727 measurementFound.ifPresent(measurementDTO -> row.setAnalyst(measurementDTO.getAnalyst()));
728
729 }
730 }
731
732 recomputeRowsValidState();
733
734 } else {
735
736
737 getModel().setBeans(null);
738 }
739 forceRevalidateModel();
740
741
742 restoreTableState();
743
744
745
746
747 forceColumnVisible(OperationsTableModel.ANALYST, notEmpty);
748
749
750 ensureColumnsWithErrorAreVisible(getModel().getRows());
751
752 } finally {
753 getModel().setLoading(false);
754 }
755 }
756 }
757 }