View Javadoc
1   package fr.ifremer.dali.ui.swing.content.manage.rule.rulelist;
2   
3   /*
4    * #%L
5    * Dali :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (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 Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import fr.ifremer.dali.dto.DaliBeans;
27  import fr.ifremer.dali.dto.configuration.control.RuleListDTO;
28  import fr.ifremer.dali.ui.swing.content.manage.rule.RulesUI;
29  import fr.ifremer.dali.ui.swing.content.manage.rule.RulesUIModel;
30  import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableModel;
31  import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableUIHandler;
32  import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
33  import org.apache.commons.lang3.StringUtils;
34  import org.jdesktop.swingx.table.TableColumnExt;
35  
36  import javax.swing.SwingUtilities;
37  import java.util.List;
38  
39  import static org.nuiton.i18n.I18n.t;
40  
41  /**
42   * Controller pour le tableau des listes de regles.
43   */
44  public class RuleListUIHandler extends AbstractDaliTableUIHandler<RuleListRowModel, RuleListUIModel, RuleListUI> {
45  
46      /**
47       * {@inheritDoc}
48       */
49      @Override
50      public void beforeInit(final RuleListUI ui) {
51          super.beforeInit(ui);
52  
53          // create model and register to the JAXX context
54          final RuleListUIModel model = new RuleListUIModel();
55          ui.setContextValue(model);
56      }
57  
58      /**
59       * {@inheritDoc}
60       */
61      @Override
62      public void afterInit(final RuleListUI ui) {
63  
64          // Initialisation de l ecran
65          initUI(ui);
66  
67          // Disable buttons
68          getUI().getDuplicateRuleListButton().setEnabled(false);
69          getUI().getDeleteRuleListButton().setEnabled(false);
70  
71          // Initialisation du tableau
72          initTable();
73  
74          // Initialisation des listeners
75          initListeners();
76  
77      }
78  
79      /**
80       * Chargement des regles.
81       *
82       * @param ruleLists Les regles
83       */
84      public void loadRuleLists(final List<RuleListDTO> ruleLists) {
85  
86          getModel().setBeans(ruleLists);
87          getModel().getRows().forEach(ruleListRowModel -> ruleListRowModel.setEditable(getModel().isSaveEnabled()));
88  
89          // auto select unique row
90          if (getModel().getRowCount() == 1) {
91              RuleListRowModel rowModel = getModel().getRows().get(0);
92              SwingUtilities.invokeLater(() -> {
93                  selectRow(rowModel);
94                  getModel().setSingleSelectedRow(rowModel);
95              });
96          }
97      }
98  
99      /**
100      * <p>clearTable.</p>
101      */
102     public void clearTable() {
103 
104         loadRuleLists(null);
105     }
106 
107     /**
108      * Initialisation du tableau.
109      */
110     private void initTable() {
111 
112         // Le tableau
113         final SwingTable table = getTable();
114 
115         // Code
116         TableColumnExt codeCol = addColumn(RuleListTableModel.CODE);
117         codeCol.setSortable(true);
118         codeCol.setEditable(false);
119 
120         // Actif
121         final TableColumnExt activeCol = addBooleanColumnToModel(RuleListTableModel.ACTIVE, table);
122         activeCol.setSortable(true);
123 
124         // Mois debut
125 //        TableColumnExt startMonthCol = addDatePickerColumnToModel(RuleListTableModel.START_MONTH, "MMMM");
126         TableColumnExt startMonthCol = addSimpleComboDataColumnToModel(RuleListTableModel.START_MONTH, getContext().getSystemService().getMonths());
127         startMonthCol.setSortable(true);
128 
129         // Mois fin
130 //        TableColumnExt endMonthCol = addDatePickerColumnToModel(RuleListTableModel.END_MONTH, "MMMM");
131         TableColumnExt endMonthCol = addSimpleComboDataColumnToModel(RuleListTableModel.END_MONTH, getContext().getSystemService().getMonths());
132         endMonthCol.setSortable(true);
133 
134         // Description
135         TableColumnExt descriptionCol = addColumn(RuleListTableModel.DESCRIPTION);
136         descriptionCol.setSortable(true);
137 
138         TableColumnExt creationDateCol = addDatePickerColumnToModel(RuleListTableModel.CREATION_DATE, getConfig().getDateTimeFormat(), false);
139         fixColumnWidth(creationDateCol, 120);
140         TableColumnExt updateDateCol = addDatePickerColumnToModel(RuleListTableModel.UPDATE_DATE, getConfig().getDateTimeFormat(), false);
141         fixColumnWidth(updateDateCol, 120);
142 
143         RuleListTableModel tableModel = new RuleListTableModel(getTable().getColumnModel());
144         table.setModel(tableModel);
145 
146         // Initialisation du tableau
147         initTable(table);
148 
149         creationDateCol.setVisible(false);
150         updateDateCol.setVisible(false);
151 
152         // Number rows visible
153         table.setVisibleRowCount(3);
154     }
155 
156     /**
157      * {@inheritDoc}
158      */
159     @Override
160     protected String[] getRowPropertiesToIgnore() {
161         return new String[]{RuleListRowModel.PROPERTY_ERRORS};
162     }
163 
164     /**
165      * {@inheritDoc}
166      */
167     @Override
168     protected boolean isRowValid(RuleListRowModel row) {
169         return super.isRowValid(row) && isRuleListValid(row);
170     }
171 
172     private boolean isRuleListValid(RuleListRowModel row) {
173 
174         if (row == getModel().getSingleSelectedRow()) {
175 
176             // remove previous errors
177             row.getErrors().clear();
178 
179             // both start and end dates must be null or not null
180             if (row.getStartMonth() == null && row.getEndMonth() != null) {
181                 DaliBeans.addError(row, t("dali.rule.ruleList.startMonth.null"), RuleListRowModel.PROPERTY_START_MONTH);
182 
183             } else if (row.getStartMonth() != null && row.getEndMonth() == null) {
184                 DaliBeans.addError(row, t("dali.rule.ruleList.endMonth.null"), RuleListRowModel.PROPERTY_END_MONTH);
185             }
186 
187             // check no program
188             if (row.isProgramsEmpty()) {
189                 DaliBeans.addError(row, t("dali.rule.ruleList.error.noProgram"), RuleListRowModel.PROPERTY_CODE);
190             }
191 
192             // check no department
193             if (row.isDepartmentsEmpty()) {
194                 DaliBeans.addError(row, t("dali.rule.ruleList.error.noDepartment"), RuleListRowModel.PROPERTY_CODE);
195             }
196 
197             // check no control rule
198             if (row.isControlRulesEmpty()) {
199                 DaliBeans.addError(row, t("dali.rule.ruleList.error.noControlRule"), RuleListRowModel.PROPERTY_CODE);
200             }
201 
202             // check sub-models
203             RulesUIModel rulesUIModel = getRulesUI().getModel();
204             if (!rulesUIModel.getProgramsUIModel().isValid()
205                     || !rulesUIModel.getDepartmentsUIModel().isValid()
206                     || !rulesUIModel.getControlRuleUIModel().isValid()
207                     || !rulesUIModel.getPmfmUIModel().isValid()) {
208 
209                 DaliBeans.addError(row, t("dali.rule.ruleList.error"), RuleListRowModel.PROPERTY_CODE);
210             }
211 
212         }
213         return row.isErrorsEmpty();
214     }
215 
216     /**
217      * <p>getRulesUI.</p>
218      *
219      * @return a {@link fr.ifremer.dali.ui.swing.content.manage.rule.RulesUI} object.
220      */
221     public RulesUI getRulesUI() {
222         return getUI().getParentContainer(RulesUI.class);
223     }
224 
225     /**
226      * Initialisation des listeners.
227      */
228     private void initListeners() {
229 
230         // Listener sur le tableau
231         getModel().addPropertyChangeListener(RuleListUIModel.PROPERTY_SINGLE_ROW_SELECTED, evt -> {
232 
233             final RulesUI rulesUI = getRulesUI();
234             // On efface les informations sur le PSFM vu qu'il n'est pas sélectioné par default
235             rulesUI.getControlPmfmTableUI().getHandler().clearTable();
236             rulesUI.getControlRuleTableUI().getHandler().clearControlRuleInformation();
237 
238             final RuleListRowModel ruleList = getModel().getSingleSelectedRow();
239             // Si un seul element a ete selectionne
240             if (ruleList != null) {
241 
242                 // Chargement des ProgrammesControle
243                 rulesUI.getControlProgramTableUI().getHandler().loadPrograms(ruleList.getPrograms(), !ruleList.isEditable());
244 
245                 // Chargement des ServicesControle
246                 rulesUI.getControlDepartmentTableUI().getHandler().loadDepartments(ruleList.getDepartments(), !ruleList.isEditable());
247 
248                 //Chargement des ReglesControle
249                 rulesUI.getControlRuleTableUI().getHandler().loadControlRules(ruleList.getControlRules(), !ruleList.isEditable());
250 
251             } else {
252                 rulesUI.getControlProgramTableUI().getHandler().clearTable();
253                 rulesUI.getControlDepartmentTableUI().getHandler().clearTable();
254                 rulesUI.getControlRuleTableUI().getHandler().clearTable();
255             }
256 
257         });
258 
259         // Add listener on saveEnabled property to disable change (Mantis #47532)
260         getModel().addPropertyChangeListener(RuleListUIModel.PROPERTY_SAVE_ENABLED, evt -> {
261             getModel().getRows().forEach(ruleListRowModel -> ruleListRowModel.setEditable(getModel().isSaveEnabled()));
262             getUI().getRulesTableUI().invalidate();
263             getUI().getRulesTableUI().repaint();
264             if (getModel().getSingleSelectedRow() != null) {
265                 getModel().setSingleSelectedRow(getModel().getSingleSelectedRow());
266             }
267         });
268 
269     }
270 
271     /**
272      * {@inheritDoc}
273      */
274     @Override
275     protected void onRowModified(int rowIndex, RuleListRowModel row, String propertyName, Integer propertyIndex, Object oldValue, Object newValue) {
276         super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue);
277 
278         row.setDirty(true);
279     }
280 
281     /**
282      * {@inheritDoc}
283      */
284     @Override
285     protected void onRowsAdded(List<RuleListRowModel> addedRows) {
286         super.onRowsAdded(addedRows);
287 
288         if (addedRows.size() == 1) {
289             final RuleListRowModel row = addedRows.get(0);
290 
291             // if the new code is already set (means that the new row is a duplication), don't ask a new code (Mantis #40662)
292             if (!row.isNewCode()) {
293 
294                 if (checkNewCode(row)) {
295 
296                     row.setActive(true);
297 
298                     // add the department of the recorder
299                     // Removed (see Mantis #40474)
300 //                if (getContext().getDataContext().getRecorderDepartmentId() != null) {
301 //                    DepartmentDTO department = getContext().getReferentialService().getDepartmentById(getContext().getDataContext().getRecorderDepartmentId());
302 //                    if (!row.containsDepartments(department)) {
303 //                        row.addDepartments(department);
304 //                    }
305 //                }
306 
307                     row.setNewCode(true);
308                     setFocusOnCell(row);
309 
310                 } else {
311 
312                     // if code is invalid, remove this row
313                     SwingUtilities.invokeLater(() -> {
314                         getModel().deleteRow(row);
315                         getModel().setSingleSelectedRow(null);
316                     });
317 
318                 }
319             }
320         }
321     }
322 
323     private boolean checkNewCode(RuleListRowModel row) {
324 
325         boolean edit = StringUtils.isNotBlank(row.getCode());
326 
327         // ask for new code
328         String newCode = (String) getContext().getDialogHelper().showInputDialog(
329                 getUI(),
330                 t("dali.rule.ruleList.setCode"),
331                 edit ? t("dali.rule.ruleList.editCode.title") : t("dali.rule.ruleList.setCode.title"),
332                 null,
333                 row.getCode());
334 
335         if (checkCodeDuplicates(newCode, row, edit)) {
336             row.setCode(newCode);
337             return true;
338         }
339 
340         return false;
341     }
342 
343     /**
344      * <p>checkCodeDuplicates.</p>
345      *
346      * @param newCode a {@link java.lang.String} object.
347      * @return a boolean.
348      */
349     public boolean checkCodeDuplicates(String newCode) {
350         return checkCodeDuplicates(newCode, null, false);
351     }
352 
353     /**
354      * <p>checkCodeDuplicates.</p>
355      *
356      * @param newCode    a {@link java.lang.String} object.
357      * @param currentRow a {@link RuleListRowModel} object.
358      * @param edit       a boolean.
359      * @return a boolean.
360      */
361     private boolean checkCodeDuplicates(String newCode, RuleListRowModel currentRow, boolean edit) {
362 
363         if (StringUtils.isBlank(newCode)) {
364             return false;
365         }
366 
367         newCode = newCode.trim();
368 
369         // check if new code is already in UI
370         for (RuleListRowModel otherRow : getModel().getRows()) {
371             if (currentRow == otherRow) continue;
372             if (newCode.equalsIgnoreCase(otherRow.getCode())) {
373                 getContext().getDialogHelper().showErrorDialog(
374                         t("dali.error.alreadyExists.referential", t("dali.rule.ruleList.title"), newCode, t("dali.property.referential.national")),
375                         edit ? t("dali.rule.ruleList.editCode.title") : t("dali.rule.ruleList.setCode.title")
376                 );
377                 return false;
378             }
379         }
380 
381         // check if new code is already in bdd
382         if (getContext().getRuleListService().ruleListCodeExists(newCode)) {
383             getContext().getDialogHelper().showErrorDialog(
384                     t("dali.error.alreadyExists.referential", t("dali.rule.ruleList.title"), newCode, t("dali.property.referential.national")),
385                     edit ? t("dali.rule.ruleList.editCode.title") : t("dali.rule.ruleList.setCode.title")
386             );
387             return false;
388         }
389 
390         return true;
391     }
392 
393     /**
394      * <p>editRuleListCode.</p>
395      */
396     public void editRuleListCode() {
397         RuleListRowModel row = getModel().getSingleSelectedRow();
398         if (row != null && row.isNewCode()) {
399             if (checkNewCode(row)) {
400                 row.setDirty(true);
401             }
402         }
403     }
404 
405     /**
406      * {@inheritDoc}
407      */
408     @Override
409     public AbstractDaliTableModel<RuleListRowModel> getTableModel() {
410         return (RuleListTableModel) getTable().getModel();
411     }
412 
413     /**
414      * {@inheritDoc}
415      */
416     @Override
417     public SwingTable getTable() {
418         return ui.getRulesTableUI();
419     }
420 }