OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
132 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.ui.light;
15
 
16
import org.openconcerto.sql.Configuration;
17
import org.openconcerto.sql.Log;
18
import org.openconcerto.sql.element.SQLElement;
19
import org.openconcerto.sql.model.FieldMapper;
20
import org.openconcerto.sql.model.SQLField;
21
import org.openconcerto.sql.model.SQLRow;
22
import org.openconcerto.sql.model.SQLRowValues;
23
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
24
import org.openconcerto.sql.model.SQLTable;
25
import org.openconcerto.sql.view.EditPanel.EditMode;
26
import org.openconcerto.ui.group.Group;
27
import org.openconcerto.ui.group.Item;
28
import org.openconcerto.ui.light.ComboValueConvertor;
29
import org.openconcerto.ui.light.CustomEditorProvider;
30
import org.openconcerto.ui.light.JSONToLightUIConvertor;
31
import org.openconcerto.ui.light.LightUICheckBox;
32
import org.openconcerto.ui.light.LightUIComboBox;
33
import org.openconcerto.ui.light.LightUIDate;
34
import org.openconcerto.ui.light.LightUIElement;
35
import org.openconcerto.ui.light.LightUIFrame;
36
import org.openconcerto.ui.light.StringValueConvertor;
37
import org.openconcerto.utils.io.JSONConverter;
38
 
39
import java.sql.SQLException;
40
import java.sql.Timestamp;
41
import java.util.Date;
42
import java.util.Map;
43
 
44
import net.minidev.json.JSONObject;
45
 
46
public class LightEditFrame extends LightUIFrame {
47
    private static final String EDIT_MODE_JSON_KEY = "edit-mode";
48
 
49
    private Group group;
50
    private SQLRowValues sqlRow;
51
 
52
    private EditMode editMode = EditMode.READONLY;
53
 
54
    // Init from json constructor
55
    public LightEditFrame(final JSONObject json) {
56
        super(json);
57
    }
58
 
59
    // Clone constructor
60
    public LightEditFrame(final LightEditFrame frame) {
61
        super(frame);
62
        this.sqlRow = frame.sqlRow;
63
        this.group = frame.group;
64
        this.editMode = frame.editMode;
65
    }
66
 
67
    public LightEditFrame(final Configuration conf, final Group group, final SQLRowValues sqlRow, final LightUIFrame parentFrame, final EditMode editMode) {
68
        super(group.getId() + ".edit.frame");
69
        this.setType(TYPE_FRAME);
70
        this.setParent(parentFrame);
71
 
72
        this.sqlRow = sqlRow;
73
        this.group = group;
74
 
75
        this.setEditMode(editMode);
76
    }
77
 
78
    public void setEditMode(final EditMode editMode) {
79
        this.editMode = editMode;
80
        if (editMode.equals(EditMode.READONLY)) {
81
            this.setReadOnly(true);
82
        } else {
83
            this.setReadOnly(false);
84
        }
85
    }
86
 
87
    /**
88
     * Commit the SQLRowValues attached to this frame
89
     *
90
     * @param configuration Current configuration
91
     * @return The inserted SQLRow
92
     */
93
    public SQLRow commitSqlRow(final Configuration configuration) {
94
        if (this.editMode.equals(EditMode.READONLY)) {
95
            throw new IllegalArgumentException("Impossible to commit values when the frame is read only");
96
        }
97
        final SQLElement sqlElement = configuration.getDirectory().getElement(this.sqlRow.getTable());
98
        try {
99
            return this.sqlRow.prune(sqlElement.getPrivateGraph()).commit();
100
        } catch (final SQLException ex) {
101
            throw new IllegalArgumentException("Unable to commit SQLRowValues, edit frame ID: " + this.getId());
102
        }
103
    }
104
 
105
    public EditMode getEditMode() {
106
        return this.editMode;
107
    }
108
 
109
    public Group getGroup() {
110
        return this.group;
111
    }
112
 
113
    public SQLRowValues getSqlRow() {
114
        return this.sqlRow;
115
    }
116
 
117
    /**
118
     * Update the SQLRowValues attached to this frame
119
     *
120
     * @param conf
121
     * @param userId
122
     */
123
    public void updateRow(final Configuration configuration, final int userId) {
124
        if (this.editMode.equals(EditMode.READONLY)) {
125
            throw new IllegalArgumentException("Impossible to update values when the frame is read only");
126
        }
127
        this.updateRow(configuration, this.group, userId);
128
    }
129
 
130
    private void updateRow(final Configuration configuration, final Group group, final int userId) {
131
        final FieldMapper fieldMapper = configuration.getFieldMapper();
132
        if (fieldMapper == null) {
133
            throw new IllegalStateException("null field mapper");
134
        }
135
 
136
        final SQLElement sqlElement = configuration.getDirectory().getElement(this.sqlRow.getTable());
137
        final Map<String, ComboValueConvertor<?>> valueConvertors = sqlElement.getComboConvertors();
138
 
139
        Map<String, CustomEditorProvider> customEditors = null;
140
        if (this.editMode.equals(EditMode.CREATION)) {
141
            customEditors = sqlElement.getCustomEditorProviderForCreation(configuration, userId);
142
        } else {
143
            customEditors = sqlElement.getCustomEditorProviderForModification(configuration, this.sqlRow, userId);
144
        }
145
 
146
        this.createRowValues(configuration, fieldMapper, this.group, valueConvertors, customEditors);
147
        this.setMetaData(userId);
148
    }
149
 
150
    final protected void createRowValues(final Configuration conf, final FieldMapper fieldMapper, final Group group, final Map<String, ComboValueConvertor<?>> valueConvertors,
151
            final Map<String, CustomEditorProvider> customEditors) {
152
        final int itemCount = group.getSize();
153
        for (int i = 0; i < itemCount; i++) {
154
            final Item item = group.getItem(i);
155
            if (item instanceof Group) {
156
                this.createRowValues(conf, fieldMapper, (Group) item, valueConvertors, customEditors);
157
            } else {
158
                final SQLField field = fieldMapper.getSQLFieldForItem(item.getId());
159
                if (field != null) {
160
                    final LightUIElement uiElement = this.findChild(item.getId(), false);
161
 
162
                    if (uiElement == null) {
163
                        throw new IllegalArgumentException("Impossible to find UI Element with id: " + item.getId());
164
                    }
165
 
166
                    if (!valueConvertors.containsKey(item.getId()) && !customEditors.containsKey(item.getId())) {
167
                        this.putValueFromUserControl(conf, field, uiElement);
168
                    } else if (valueConvertors.containsKey(item.getId())) {
169
                        if (!(uiElement instanceof LightUIComboBox)) {
170
                            throw new IllegalArgumentException("The UI Element with ID " + item.getId() + ", must be an instance of LightUIComboBox");
171
                        }
172
                        final LightUIComboBox combo = (LightUIComboBox) uiElement;
173
                        if (combo.hasSelectedValue() && combo.getSelectedValue().getId() != 0) {
174
                            final ComboValueConvertor<?> valueConvertor = valueConvertors.get(item.getId());
175
                            if (valueConvertor instanceof StringValueConvertor) {
176
                                this.sqlRow.put(field.getFieldName(), ((StringValueConvertor) valueConvertor).getIdFromIndex(combo.getSelectedValue().getId()));
177
                            } else {
178
                                final int selectedId = combo.getSelectedValue().getId();
179
                                this.sqlRow.put(field.getFieldName(), selectedId);
180
                            }
181
                        } else {
182
                            this.sqlRow.put(field.getFieldName(), null);
183
                        }
184
                    } else if (customEditors.containsKey(item.getId())) {
185
                        Log.get().warning("Unable to save value of element: " + item.getId());
186
                    }
187
                } else {
188
                    Log.get().warning("No field attached to " + item.getId());
189
                }
190
            }
191
        }
192
    }
193
 
194
    final protected void putValueFromUserControl(final Configuration conf, final SQLField field, final LightUIElement uiElement) {
195
        final Class<?> fieldType = field.getType().getJavaType();
196
        if (field.isKey()) {
197
            if (!(uiElement instanceof LightUIComboBox)) {
198
                throw new IllegalArgumentException("Invalid UI Element for field: " + field.getName() + ". When field is foreign key, UI Element must be a LightUIDate");
199
            }
200
            final LightUIComboBox combo = (LightUIComboBox) uiElement;
201
 
202
            if (combo.hasSelectedValue()) {
203
                final SQLRowValues tmp = new SQLRowValues(this.sqlRow.getTable()).put(field.getName(), null);
204
                conf.getDirectory().getShowAs().expand(tmp);
205
                final SQLRowValues toFetch = (SQLRowValues) tmp.getForeign(field.getName());
206
                tmp.remove(field.getName());
207
 
208
                final SQLRowValues fetched = SQLRowValuesListFetcher.create(toFetch).fetchOne(combo.getSelectedValue().getId());
209
                if (fetched == null) {
210
                    throw new IllegalArgumentException("Impossible to find Row in database - table: " + field.getForeignTable().getName() + ", id: " + combo.getSelectedValue().getId());
211
                }
212
 
213
                this.sqlRow.put(field.getFieldName(), fetched);
214
            } else {
215
                this.sqlRow.put(field.getFieldName(), null);
216
            }
217
        } else if (fieldType.equals(String.class)) {
218
            this.sqlRow.put(field.getFieldName(), uiElement.getValue());
219
        } else if (fieldType.equals(Date.class)) {
220
            if (!(uiElement instanceof LightUIDate)) {
221
                throw new IllegalArgumentException("Invalid UI Element for field: " + field.getName() + ". When field is Date, UI Element must be a LightUIDate");
222
            }
223
            this.sqlRow.put(field.getFieldName(), ((LightUIDate) uiElement).getValueAsDate());
224
        } else if (fieldType.equals(Boolean.class)) {
225
            if (!(uiElement instanceof LightUICheckBox)) {
226
                throw new IllegalArgumentException("Invalid UI Element for field: " + field.getName() + ". When field is Boolean, UI Element must be a LightUICheckBox");
227
            }
228
            this.sqlRow.put(field.getFieldName(), ((LightUICheckBox) uiElement).isChecked());
229
        } else if (fieldType.equals(Timestamp.class)) {
230
            if (!(uiElement instanceof LightUIDate)) {
231
                throw new IllegalArgumentException("Invalid UI Element for field: " + field.getName() + ". When field is Date, UI Element must be a LightUIDate");
232
            }
233
            this.sqlRow.put(field.getFieldName(), ((LightUIDate) uiElement).getValueAsDate());
234
        } else if (fieldType.equals(Integer.class)) {
235
            if (uiElement.getValue() != null && !uiElement.getValue().trim().isEmpty()) {
236
                if (!uiElement.getValue().matches("^-?\\d+$")) {
237
                    throw new IllegalArgumentException("Invalid value for field: " + field.getName() + " value: " + uiElement.getValue());
238
                }
239
                this.sqlRow.put(field.getFieldName(), Integer.parseInt(uiElement.getValue()));
240
            } else {
241
                this.sqlRow.put(field.getFieldName(), null);
242
            }
243
        } else {
244
            Log.get().warning("unsupported type " + fieldType.getName());
245
        }
246
    }
247
 
248
    /**
249
     * Save all referent rows store in LightRowValuesTable
250
     *
251
     * @param group Element edit group
252
     * @param frame Element edit frame
253
     * @param row Element saved row
254
     * @param customEditors List of custom editors used in element edit frame
255
     */
256
    final public void saveReferentRows(final Configuration configuration, final SQLRow parentSqlRow, final Map<String, CustomEditorProvider> customEditors) {
257
        this.saveReferentRows(configuration, this.group, parentSqlRow, customEditors);
258
    }
259
 
260
    final private void saveReferentRows(final Configuration configuration, final Group group, final SQLRow parentSqlRow, final Map<String, CustomEditorProvider> customEditors) {
261
        for (int i = 0; i < group.getSize(); i++) {
262
            final Item item = group.getItem(i);
263
            if (item instanceof Group) {
264
                this.saveReferentRows(configuration, (Group) item, parentSqlRow, customEditors);
265
            } else if (customEditors.containsKey(item.getId())) {
266
                final LightUIElement element = this.findChild(item.getId(), false);
267
                if (element instanceof LightRowValuesTable) {
268
                    final LightRowValuesTable rowValsTable = (LightRowValuesTable) element;
269
                    final int rowValuesCount = rowValsTable.getRowValuesCount();
270
                    for (int j = 0; j < rowValuesCount; j++) {
271
                        SQLRowValues rowValues = rowValsTable.getRowValues(j);
272
                        if (!rowValues.isFrozen()) {
273
                            rowValues.put(rowValsTable.getFieldRefName(), parentSqlRow.getID());
274
                            try {
275
                                final SQLElement el = configuration.getDirectory().getElement(rowValues.getTable());
276
                                boolean insertion = !rowValues.hasID();
277
                                SQLRow rowInserted = rowValues.prune(el.getPrivateGraph()).commit();
278
                                if (insertion) {
279
                                    ((SQLElement) el).doAfterLightInsert(rowInserted);
280
                                }
281
                            } catch (SQLException e) {
282
                                throw new IllegalArgumentException(e.getMessage(), e);
283
                            }
284
                        }
285
                    }
286
                    rowValsTable.archiveDeletedRows(configuration);
287
                }
288
            }
289
        }
290
    }
291
 
292
    final protected void setMetaData(final int userId) {
293
        final SQLTable sqlTable = this.sqlRow.getTable();
294
        // FIXME: Creation user not specified.
295
        if (this.sqlRow.getObject(sqlTable.getCreationUserField().getName()) == null || this.sqlRow.getObject(sqlTable.getCreationDateField().getName()) == null) {
296
            this.sqlRow.put(sqlTable.getCreationUserField().getName(), userId);
297
            this.sqlRow.put(sqlTable.getCreationDateField().getName(), new Date());
298
        }
299
        this.sqlRow.put(sqlTable.getModifUserField().getName(), userId);
300
        this.sqlRow.put(sqlTable.getModifDateField().getName(), new Date());
301
    }
302
 
303
    @Override
304
    public String getClassName() {
305
        return this.getClass().getName();
306
    }
307
 
308
    @Override
309
    public JSONToLightUIConvertor getConvertor() {
310
        return new JSONToLightUIConvertor() {
311
 
312
            @Override
313
            public LightUIElement convert(JSONObject json) {
314
                return new LightEditFrame(json);
315
            }
316
        };
317
    }
318
 
319
    @Override
320
    public LightUIElement clone() {
321
        return new LightEditFrame(this);
322
    }
323
 
324
    // TODO: implement JSONAble on SQLRowValues and Group
325
    @Override
326
    public JSONObject toJSON() {
327
        final JSONObject json = super.toJSON();
328
        if (!this.editMode.equals(EditMode.READONLY)) {
329
            if (this.editMode.equals(EditMode.CREATION)) {
330
                json.put(EDIT_MODE_JSON_KEY, 1);
331
            } else if (this.editMode.equals(EditMode.MODIFICATION)) {
332
                json.put(EDIT_MODE_JSON_KEY, 2);
333
            }
334
        }
335
        return json;
336
    }
337
 
338
    @Override
339
    public void fromJSON(final JSONObject json) {
340
        super.fromJSON(json);
341
        final int jsonEditMode = JSONConverter.getParameterFromJSON(json, EDIT_MODE_JSON_KEY, Integer.class, 3);
342
        if (jsonEditMode == 1) {
343
            this.editMode = EditMode.CREATION;
344
        } else if (jsonEditMode == 2) {
345
            this.editMode = EditMode.MODIFICATION;
346
        } else if (jsonEditMode == 3) {
347
            this.editMode = EditMode.READONLY;
348
        }
349
    }
350
}