1 package fr.ifremer.dali.ui.swing.content.extraction.filters;
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 com.google.common.collect.Lists;
27 import fr.ifremer.dali.dto.DaliBeanFactory;
28 import fr.ifremer.dali.dto.DaliBeans;
29 import fr.ifremer.dali.dto.configuration.filter.FilterDTO;
30 import fr.ifremer.dali.dto.configuration.programStrategy.ProgramDTO;
31 import fr.ifremer.dali.dto.enums.ExtractionFilterTypeValues;
32 import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
33 import fr.ifremer.dali.dto.system.extraction.ExtractionParameterDTO;
34 import fr.ifremer.dali.dto.system.extraction.ExtractionPeriodDTO;
35 import fr.ifremer.dali.dto.system.extraction.FilterTypeDTO;
36 import fr.ifremer.dali.dto.system.extraction.PmfmPresetDTO;
37 import fr.ifremer.dali.service.DaliTechnicalException;
38 import fr.ifremer.dali.ui.swing.content.extraction.ExtractionUI;
39 import fr.ifremer.dali.ui.swing.content.extraction.filters.period.ExtractionPeriodUI;
40 import fr.ifremer.dali.ui.swing.content.manage.filter.select.SelectFilterUI;
41 import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableModel;
42 import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableUIHandler;
43 import fr.ifremer.quadrige3.core.dao.technical.Assert;
44 import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean;
45 import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
46 import jaxx.runtime.SwingUtil;
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.jdesktop.swingx.table.TableColumnExt;
50
51 import javax.swing.JOptionPane;
52 import javax.swing.SwingUtilities;
53 import javax.swing.SwingWorker;
54 import java.awt.Dimension;
55 import java.awt.event.MouseAdapter;
56 import java.awt.event.MouseEvent;
57 import java.util.Collection;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Set;
61 import java.util.concurrent.ExecutionException;
62 import java.util.stream.Collectors;
63
64 import static org.nuiton.i18n.I18n.t;
65
66
67
68
69 public class ExtractionFiltersUIHandler extends
70 AbstractDaliTableUIHandler<ExtractionFiltersRowModel, ExtractionFiltersUIModel, ExtractionFiltersUI> {
71
72
73
74
75 private static final Log LOG = LogFactory.getLog(ExtractionFiltersUIHandler.class);
76 private FilterLoader filterLoader = new FilterLoader();
77
78
79
80
81 @Override
82 public void beforeInit(final ExtractionFiltersUI ui) {
83 super.beforeInit(ui);
84
85
86 final ExtractionFiltersUIModel model = new ExtractionFiltersUIModel();
87 ui.setContextValue(model);
88 }
89
90
91
92
93 @Override
94 public void afterInit(final ExtractionFiltersUI ui) {
95
96
97 initUI(ui);
98
99
100 initTable();
101 SwingUtil.setLayerUI(ui.getExtractionsFiltersScrollPane(), ui.getTableBlockLayer());
102
103
104 initListeners();
105
106
107 loadFilters();
108 }
109
110
111
112
113 private void initTable() {
114
115
116 TableColumnExt filterTypeCol = addColumn(ExtractionFiltersTableModel.FILTER_TYPE);
117 fixColumnWidth(filterTypeCol, 150);
118
119
120 addColumn(
121 null,
122 new FilterElementsCellRenderer(getContext().getDecoratorService()),
123 ExtractionFiltersTableModel.FILTER);
124
125 ExtractionFiltersTableModel tableModel = new ExtractionFiltersTableModel(getTable().getColumnModel());
126 getTable().setModel(tableModel);
127
128
129 initTable(getTable(), true);
130
131
132 getTable().setSortable(false);
133 getTable().setEditable(false);
134
135
136 addEditionPanelBorder();
137
138
139 getTable().addMouseListener(new MouseAdapter() {
140
141 @Override
142 public void mouseClicked(MouseEvent e) {
143 if (e.getClickCount() == 2) {
144 getUI().getEditFilterButton().doClick();
145 }
146 }
147 });
148
149 }
150
151 private void initListeners() {
152
153 }
154
155
156
157
158 @Override
159 protected boolean isRowValid(ExtractionFiltersRowModel row) {
160 return getModel().getSelectedExtraction() == null || (super.isRowValid(row) && isFilterValid(row));
161 }
162
163 private boolean isFilterValid(ExtractionFiltersRowModel row) {
164
165 row.getErrors().clear();
166 ExtractionFilterTypeValues extractionFilter = ExtractionFilterTypeValues.getExtractionFilterType(row.getFilterTypeId());
167 Assert.notNull(extractionFilter);
168
169 switch (extractionFilter) {
170 case PERIOD:
171 if (row.isFilterEmpty()) {
172 DaliBeans.addError(row, t("dali.extraction.filters.error.period.empty.message"), ExtractionFiltersRowModel.PROPERTY_FILTER);
173 }
174 break;
175
176 case PROGRAM:
177 if (row.isFilterEmpty()) {
178 DaliBeans.addError(row, t("dali.extraction.filters.error.program.empty.message"), ExtractionFiltersRowModel.PROPERTY_FILTER);
179 }
180 break;
181
182 }
183
184 return row.getErrors().isEmpty();
185 }
186
187
188
189
190 @Override
191 public AbstractDaliTableModel<ExtractionFiltersRowModel> getTableModel() {
192 return (ExtractionFiltersTableModel) getTable().getModel();
193 }
194
195
196
197
198 @Override
199 public SwingTable getTable() {
200 return ui.getExtractionsFiltersTable();
201 }
202
203
204
205
206 public void loadFilters() {
207
208 if (!filterLoader.isDone()) {
209 filterLoader.cancel(true);
210 }
211
212 getModel().setLoading(true);
213 filterLoader = new FilterLoader();
214 filterLoader.execute();
215 }
216
217
218
219
220 @SuppressWarnings("unchecked")
221 public void editFilter() {
222
223 final ExtractionFiltersRowModel rowModel = getModel().getSingleSelectedRow();
224
225 if (rowModel == null) {
226 LOG.warn("no filter selected");
227 return;
228 }
229
230 SwingUtilities.invokeLater(() -> {
231
232 if (ExtractionFilterTypeValues.getExtractionFilterType(rowModel.getFilterTypeId()) == ExtractionFilterTypeValues.PERIOD) {
233
234
235 ExtractionPeriodUI periodUI = new ExtractionPeriodUI(getContext());
236 periodUI.getModel().setBeans((Collection<ExtractionPeriodDTO>) rowModel.getFilteredElements());
237 periodUI.getHandler().recomputeRowsValidState(false);
238 openDialog(periodUI);
239
240
241 if (periodUI.getModel().isValid()) {
242 FilterDTO periodFilter = rowModel.getFilter();
243 if (periodFilter == null) {
244 periodFilter = DaliBeanFactory.newFilterDTO();
245 periodFilter.setFilterTypeId(ExtractionFilterTypeValues.PERIOD.getFilterTypeId());
246 }
247
248 List<ExtractionPeriodDTO> newPeriods = periodUI.getModel().getBeans();
249
250 if (isPmfmsConfigValid(
251 DaliBeans.getFilterElementsIds(getModel().getSelectedExtraction(), ExtractionFilterTypeValues.PROGRAM),
252 newPeriods)) {
253
254
255 periodFilter.setElements(newPeriods);
256 rowModel.setFilter(periodFilter);
257 getModel().getSelectedExtraction().replaceFilter(periodFilter);
258 }
259
260 }
261
262 } else {
263
264
265 SelectFilterUI filterUI = new SelectFilterUI(getContext(), rowModel.getFilterTypeId());
266 filterUI.getModel().setSelectedElements(rowModel.getFilteredElements());
267 filterUI.setTitle(t("dali.extraction.filters.select.title", decorate(rowModel.getFilterType())));
268 openDialog(filterUI, new Dimension(1000, 600));
269
270 if (filterUI.getModel().isValid()) {
271 FilterDTO filter = rowModel.getFilter();
272 if (filter == null) {
273 filter = DaliBeanFactory.newFilterDTO();
274 filter.setFilterTypeId(rowModel.getFilterTypeId());
275 }
276
277 List<? extends QuadrigeBean> newValue = filterUI.getModel().getSelectedElements();
278 boolean valid = true;
279
280 if (filter.getFilterTypeId().equals(ExtractionFilterTypeValues.PROGRAM.getFilterTypeId())) {
281
282 valid = isPmfmsConfigValid(
283 newValue.stream().map(bean -> ((ProgramDTO) bean).getCode()).collect(Collectors.toList()),
284 DaliBeans.getExtractionPeriods(getModel().getSelectedExtraction()));
285 }
286
287 if (valid) {
288 rowModel.setFilter(filter);
289 filter.setFilterLoaded(true);
290 filter.setElements(newValue);
291 filter.setDirty(true);
292 getModel().getSelectedExtraction().replaceFilter(filter);
293 }
294 }
295
296 }
297
298 recomputeRowsValidState();
299 getModel().firePropertyChanged(ExtractionFiltersUIModel.PROPERTY_VALID, null, getModel().isValid());
300 getTable().repaint();
301
302 });
303
304 }
305
306
307
308
309
310
311
312 private boolean isPmfmsConfigValid(Collection<String> programCodes, Collection<ExtractionPeriodDTO> periods) {
313
314 if (getModel().getSelectedExtraction().getParameter() == null) return true;
315
316 ExtractionParameterDTO parameter = getModel().getSelectedExtraction().getParameter();
317
318
319 Set<PmfmDTO> allPmfms = getParentContainer(ExtractionUI.class).getHandler().getPmfmsForSelectedExtraction(programCodes, periods);
320
321 boolean valid = parameter.getPmfmPresets().stream().map(PmfmPresetDTO::getPmfm).allMatch(allPmfms::contains)
322 && allPmfms.containsAll(parameter.getPmfmResults());
323
324 if (!valid) {
325 if (getContext().getDialogHelper().showConfirmDialog(
326 t("dali.extraction.filters.invalidParameter.message"),
327 t("dali.extraction.filters.title"),
328 JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
329
330
331 getModel().getSelectedExtraction().setParameter(null);
332 getParentContainer(ExtractionUI.class).getConfigUI().getHandler().loadConfig();
333 return true;
334 } else {
335
336
337 return false;
338 }
339 } else {
340
341
342 return true;
343 }
344
345 }
346
347 private List<FilterTypeDTO> getFilterTypes() {
348 if (getModel().getFilterTypes() == null) {
349 getModel().setFilterTypes(getContext().getExtractionService().getFilterTypes());
350 }
351 return getModel().getFilterTypes();
352 }
353
354 private class FilterLoader extends SwingWorker<List<ExtractionFiltersRowModel>, Void> {
355
356 @Override
357 protected List<ExtractionFiltersRowModel> doInBackground() {
358 List<ExtractionFiltersRowModel> rows = Lists.newArrayList();
359 Map<Integer, FilterDTO> filtersByFilterTypeId = null;
360 if (getModel().getSelectedExtraction() != null) {
361
362 getContext().getExtractionService().loadFilteredElements(getModel().getSelectedExtraction());
363
364 filtersByFilterTypeId = DaliBeans.mapByProperty(getModel().getSelectedExtraction().getFilters(), FilterDTO.PROPERTY_FILTER_TYPE_ID);
365 }
366
367 for (FilterTypeDTO filterType : getFilterTypes()) {
368 ExtractionFiltersRowModel rowModel = getTableModel().createNewRow();
369 rowModel.setValid(true);
370 rowModel.setFilterType(filterType);
371
372 if (filtersByFilterTypeId != null) {
373 rowModel.setFilter(filtersByFilterTypeId.get(filterType.getId()));
374 }
375
376 rows.add(rowModel);
377 }
378
379 return rows;
380 }
381
382 @Override
383 protected void done() {
384 try {
385 if (isCancelled()) {
386 return;
387 }
388 List<ExtractionFiltersRowModel> rows = get();
389 getModel().setLoading(true);
390 getTable().setVisibleRowCount(rows.size());
391 getModel().setRows(rows);
392 recomputeRowsValidState();
393 if (rowsHaveFilteredElements(rows)) {
394 getModel().firePropertyChanged(ExtractionFiltersUIModel.PROPERTY_VALID, null, getModel().isValid());
395 }
396
397 } catch (InterruptedException | ExecutionException e) {
398 throw new DaliTechnicalException(e.getMessage(), e);
399 } finally {
400 getModel().setLoading(false);
401 }
402 }
403
404 private boolean rowsHaveFilteredElements(List<ExtractionFiltersRowModel> rows) {
405 for (ExtractionFiltersRowModel row : rows) {
406 if (!row.isFilterEmpty()) return true;
407 }
408 return false;
409 }
410 }
411 }