OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 156 | Details | Compare with Previous | 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.SQLTable;
24
import org.openconcerto.sql.view.EditPanel.EditMode;
142 ilm 25
import org.openconcerto.sql.view.list.ListSQLLine;
26
import org.openconcerto.sql.view.list.SQLTableModelLinesSourceOffline;
132 ilm 27
import org.openconcerto.ui.group.Group;
28
import org.openconcerto.ui.group.Item;
29
import org.openconcerto.ui.light.CustomEditorProvider;
30
import org.openconcerto.ui.light.LightUICheckBox;
31
import org.openconcerto.ui.light.LightUIComboBox;
32
import org.openconcerto.ui.light.LightUIDate;
33
import org.openconcerto.ui.light.LightUIElement;
34
import org.openconcerto.ui.light.LightUIFrame;
35
import org.openconcerto.utils.io.JSONConverter;
36
 
156 ilm 37
import java.io.IOException;
38
import java.io.ObjectInput;
39
import java.io.ObjectOutput;
142 ilm 40
import java.math.BigDecimal;
132 ilm 41
import java.sql.SQLException;
42
import java.sql.Timestamp;
43
import java.util.Date;
174 ilm 44
import java.util.HashMap;
45
import java.util.List;
132 ilm 46
import java.util.Map;
142 ilm 47
import java.util.concurrent.Future;
132 ilm 48
 
49
import net.minidev.json.JSONObject;
50
 
51
public class LightEditFrame extends LightUIFrame {
52
    private static final String EDIT_MODE_JSON_KEY = "edit-mode";
53
 
54
    private Group group;
55
    private SQLRowValues sqlRow;
56
 
57
    private EditMode editMode = EditMode.READONLY;
58
 
156 ilm 59
    public LightEditFrame() {
60
        // Serialization
61
    }
62
 
132 ilm 63
    // Init from json constructor
64
    public LightEditFrame(final JSONObject json) {
65
        super(json);
66
    }
67
 
68
    // Clone constructor
69
    public LightEditFrame(final LightEditFrame frame) {
70
        super(frame);
71
        this.sqlRow = frame.sqlRow;
72
        this.group = frame.group;
73
        this.editMode = frame.editMode;
74
    }
75
 
76
    public LightEditFrame(final Configuration conf, final Group group, final SQLRowValues sqlRow, final LightUIFrame parentFrame, final EditMode editMode) {
77
        super(group.getId() + ".edit.frame");
78
        this.setType(TYPE_FRAME);
79
        this.setParent(parentFrame);
80
 
81
        this.sqlRow = sqlRow;
82
        this.group = group;
83
 
84
        this.setEditMode(editMode);
85
    }
86
 
87
    public void setEditMode(final EditMode editMode) {
88
        this.editMode = editMode;
89
        if (editMode.equals(EditMode.READONLY)) {
90
            this.setReadOnly(true);
91
        } else {
92
            this.setReadOnly(false);
93
        }
94
    }
95
 
96
    /**
97
     * Commit the SQLRowValues attached to this frame
98
     *
142 ilm 99
     * @param configuration - Current configuration
100
     *
132 ilm 101
     * @return The inserted SQLRow
142 ilm 102
     *
103
     * @throws SQLException When an error occur in SQLRowValues.commit()
132 ilm 104
     */
142 ilm 105
    public SQLRow commitSqlRow(final Configuration configuration) throws SQLException {
132 ilm 106
        if (this.editMode.equals(EditMode.READONLY)) {
107
            throw new IllegalArgumentException("Impossible to commit values when the frame is read only");
108
        }
109
        final SQLElement sqlElement = configuration.getDirectory().getElement(this.sqlRow.getTable());
110
        try {
111
            return this.sqlRow.prune(sqlElement.getPrivateGraph()).commit();
112
        } catch (final SQLException ex) {
142 ilm 113
            throw ex;
132 ilm 114
        }
115
    }
116
 
117
    public EditMode getEditMode() {
118
        return this.editMode;
119
    }
120
 
121
    public Group getGroup() {
122
        return this.group;
123
    }
124
 
125
    public SQLRowValues getSqlRow() {
126
        return this.sqlRow;
127
    }
128
 
129
    /**
130
     * Update the SQLRowValues attached to this frame
131
     *
132
     * @param conf
133
     * @param userId
134
     */
142 ilm 135
    public void updateRow(final Configuration configuration, final String sessionSecurityToken, final int userId) {
132 ilm 136
        if (this.editMode.equals(EditMode.READONLY)) {
137
            throw new IllegalArgumentException("Impossible to update values when the frame is read only");
138
        }
142 ilm 139
        this.updateRow(configuration, this.group, sessionSecurityToken, userId);
132 ilm 140
    }
141
 
142 ilm 142
    private void updateRow(final Configuration configuration, final Group group, final String sessionSecurityToken, final int userId) {
132 ilm 143
        final FieldMapper fieldMapper = configuration.getFieldMapper();
144
        if (fieldMapper == null) {
145
            throw new IllegalStateException("null field mapper");
146
        }
147
 
148
        final SQLElement sqlElement = configuration.getDirectory().getElement(this.sqlRow.getTable());
149
 
174 ilm 150
        final List<CustomRowEditor> customRowEditors = sqlElement.getCustomRowEditors(configuration, sessionSecurityToken);
151
 
152
        final Map<String, CustomRowEditor> customEditors = new HashMap<>(customRowEditors.size());
153
        for (CustomRowEditor e : customRowEditors) {
154
            customEditors.put(e.getItemId(), e);
132 ilm 155
        }
142 ilm 156
        this.createRowValues(configuration, sqlElement, fieldMapper, this.group, customEditors);
132 ilm 157
        this.setMetaData(userId);
158
    }
159
 
174 ilm 160
    protected final void createRowValues(final Configuration configuration, final SQLElement sqlElement, final FieldMapper fieldMapper, final Group group,
161
            final Map<String, CustomRowEditor> customEditors) {
132 ilm 162
        final int itemCount = group.getSize();
163
        for (int i = 0; i < itemCount; i++) {
164
            final Item item = group.getItem(i);
165
            if (item instanceof Group) {
142 ilm 166
                this.createRowValues(configuration, sqlElement, fieldMapper, (Group) item, customEditors);
132 ilm 167
            } else {
168
                final SQLField field = fieldMapper.getSQLFieldForItem(item.getId());
169
                if (field != null) {
144 ilm 170
                    final LightUIElement uiElement = this.findChildByID(item.getId(), LightUIElement.class);
132 ilm 171
 
172
                    if (uiElement == null) {
173
                        throw new IllegalArgumentException("Impossible to find UI Element with id: " + item.getId());
174
                    }
175
 
142 ilm 176
                    if (!uiElement.isNotSaved()) {
177
                        this.putValueFromUserControl(configuration, sqlElement, field, uiElement, customEditors);
132 ilm 178
                    }
179
                } else {
174 ilm 180
                    final LightUIElement uiElement = this.findChildByID(item.getId(), LightUIElement.class);
181
                    if (uiElement == null) {
182
                        throw new IllegalArgumentException("Impossible to find UI Element with id: " + item.getId());
183
                    }
184
                    if (customEditors.containsKey(uiElement.getId())) {
185
                        final CustomRowEditor customEditor = customEditors.get(uiElement.getId());
186
                        customEditor.store(uiElement, this.sqlRow);
187
                    } else {
188
                        Log.get().warning("No field attached to " + item.getId());
189
                    }
132 ilm 190
                }
191
            }
192
        }
193
    }
194
 
156 ilm 195
    protected final void putValueFromUserControl(final Configuration configuration, final SQLElement sqlElement, final SQLField sqlField, final LightUIElement uiElement,
174 ilm 196
            final Map<String, CustomRowEditor> customEditors) {
142 ilm 197
        if (!uiElement.isNotSaved()) {
198
            final Class<?> fieldType = sqlField.getType().getJavaType();
199
            if (customEditors.containsKey(uiElement.getId())) {
174 ilm 200
                final CustomRowEditor customEditor = customEditors.get(uiElement.getId());
201
                customEditor.store(uiElement, this.sqlRow);
202
            } else {
142 ilm 203
                final String fieldName = sqlField.getFieldName();
204
                if (sqlField.isKey()) {
205
                    if (!(uiElement instanceof LightUIComboBox)) {
206
                        throw new IllegalArgumentException("Invalid UI Element for field: " + fieldName + ". When field is foreign key, UI Element must be a LightUIDate");
207
                    }
208
                    final LightUIComboBox combo = (LightUIComboBox) uiElement;
132 ilm 209
 
142 ilm 210
                    if (combo.hasSelectedValue()) {
211
                        this.sqlRow.put(fieldName, combo.getSelectedValue().getId());
212
                    } else {
213
                        this.sqlRow.put(fieldName, null);
214
                    }
215
                } else {
216
                    final String value = uiElement.getValue();
217
                    if (value == null && !sqlField.isNullable()) {
218
                        Log.get().warning("ignoring null value for not nullable field " + fieldName + " from table " + sqlField.getTable().getName());
219
                    } else {
220
                        if (fieldType.equals(String.class)) {
221
                            // FIXME check string size against field size
222
                            this.sqlRow.put(fieldName, value);
223
                        } else if (fieldType.equals(Date.class)) {
224
                            if (!(uiElement instanceof LightUIDate)) {
225
                                throw new IllegalArgumentException("Invalid UI Element for field: " + fieldName + ". When field is Date, UI Element must be a LightUIDate");
226
                            }
227
                            this.sqlRow.put(fieldName, ((LightUIDate) uiElement).getValueAsDate());
228
                        } else if (fieldType.equals(Boolean.class)) {
229
                            if (!(uiElement instanceof LightUICheckBox)) {
230
                                throw new IllegalArgumentException("Invalid UI Element for field: " + fieldName + ". When field is Boolean, UI Element must be a LightUICheckBox");
231
                            }
232
                            this.sqlRow.put(fieldName, ((LightUICheckBox) uiElement).isChecked());
233
                        } else if (fieldType.equals(Timestamp.class)) {
234
                            if (!(uiElement instanceof LightUIDate)) {
235
                                throw new IllegalArgumentException("Invalid UI Element for field: " + fieldName + ". When field is Date, UI Element must be a LightUIDate");
236
                            }
237
                            this.sqlRow.put(fieldName, ((LightUIDate) uiElement).getValueAsDate());
238
                        } else if (fieldType.equals(Integer.class)) {
239
                            if (value != null && !value.trim().isEmpty()) {
240
                                if (!value.matches("^-?\\d+$")) {
241
                                    throw new IllegalArgumentException("Invalid value for field: " + fieldName + " value: " + value);
242
                                }
243
                                this.sqlRow.put(fieldName, Integer.parseInt(value));
244
                            } else {
245
                                this.sqlRow.put(fieldName, null);
246
                            }
247
                        } else if (fieldType.equals(Double.class) || fieldType.equals(Float.class) || fieldType.equals(BigDecimal.class)) {
248
                            if (value != null && !value.trim().isEmpty()) {
249
                                try {
250
                                    this.sqlRow.put(fieldName, new BigDecimal(value));
251
                                } catch (final Exception ex) {
252
                                    throw new IllegalArgumentException("Invalid value for field: " + fieldName + " value: " + value);
253
                                }
132 ilm 254
 
142 ilm 255
                            } else {
256
                                this.sqlRow.put(fieldName, null);
257
                            }
258
                        } else {
259
                            Log.get().warning("unsupported type " + fieldName);
260
                        }
261
                    }
132 ilm 262
                }
263
            }
264
        }
265
    }
266
 
267
    /**
268
     * Save all referent rows store in LightRowValuesTable
269
     *
270
     * @param group Element edit group
271
     * @param frame Element edit frame
272
     * @param row Element saved row
273
     * @param customEditors List of custom editors used in element edit frame
274
     */
174 ilm 275
    @Deprecated
276
    public final void saveReferentRows(final Configuration configuration, final SQLRow parentSqlRow, final Map<String, CustomEditorProvider> customEditors, final String sessionSecurityToken) {
142 ilm 277
        this.saveReferentRows(configuration, this.group, parentSqlRow, customEditors, sessionSecurityToken);
132 ilm 278
    }
279
 
174 ilm 280
    @Deprecated
281
    private final void saveReferentRows(final Configuration configuration, final Group group, final SQLRow parentSqlRow, final Map<String, CustomEditorProvider> customEditors,
142 ilm 282
            final String sessionSecurityToken) {
132 ilm 283
        for (int i = 0; i < group.getSize(); i++) {
284
            final Item item = group.getItem(i);
285
            if (item instanceof Group) {
142 ilm 286
                this.saveReferentRows(configuration, (Group) item, parentSqlRow, customEditors, sessionSecurityToken);
132 ilm 287
            } else if (customEditors.containsKey(item.getId())) {
144 ilm 288
                final LightUIElement element = this.findChildByID(item.getId(), LightUIElement.class);
142 ilm 289
                if (element instanceof LightForeignRowValuesTableOffline) {
290
                    final LightForeignRowValuesTableOffline foreignTable = (LightForeignRowValuesTableOffline) element;
291
                    for (int j = 0; j < foreignTable.getRowsCount(); j++) {
292
                        final ListSQLLine listLine = foreignTable.getModel().getRow(j);
293
                        final SQLRowValues rowVals = listLine.getRow().createEmptyUpdateRow();
294
                        rowVals.put(foreignTable.getForeignField().getName(), parentSqlRow.getID());
295
                        ((SQLTableModelLinesSourceOffline) foreignTable.getModel().getLinesSource()).updateRow(listLine.getID(), rowVals);
132 ilm 296
                    }
142 ilm 297
                    final Future<?> fCommit = foreignTable.commitRows();
298
 
299
                    try {
300
                        fCommit.get();
301
                    } catch (final Exception ex) {
302
                        throw new IllegalArgumentException(ex);
303
                    }
132 ilm 304
                }
305
            }
306
        }
307
    }
308
 
151 ilm 309
    // FIXME use SQLRowValues method
310
    protected final void setMetaData(final int userId) {
132 ilm 311
        final SQLTable sqlTable = this.sqlRow.getTable();
151 ilm 312
        final Date now = new Date();
313
        // FIXME only set those fields at insertion time
156 ilm 314
        if (sqlTable.getCreationUserField() != null) {
315
            if (this.sqlRow.getObject(sqlTable.getCreationUserField().getName()) == null || this.sqlRow.getObject(sqlTable.getCreationDateField().getName()) == null) {
316
                setFieldValue(this.sqlRow, sqlTable.getCreationUserField(), false, userId);
317
                setFieldValue(this.sqlRow, sqlTable.getCreationDateField(), false, now);
318
            }
132 ilm 319
        }
156 ilm 320
        if (sqlTable.getModifUserField() != null) {
321
            setFieldValue(this.sqlRow, sqlTable.getModifUserField(), false, userId);
322
            setFieldValue(this.sqlRow, sqlTable.getModifDateField(), false, now);
323
        }
132 ilm 324
    }
325
 
151 ilm 326
    static private boolean setFieldValue(final SQLRowValues vals, final SQLField f, final boolean remove, final Object val) {
327
        if (f == null)
328
            return false;
329
        if (remove)
330
            vals.remove(f.getName());
331
        else
332
            vals.put(f.getName(), val);
333
        return true;
334
    }
335
 
132 ilm 336
    @Override
337
    public String getClassName() {
338
        return this.getClass().getName();
339
    }
340
 
341
    @Override
342
    public LightUIElement clone() {
343
        return new LightEditFrame(this);
344
    }
345
 
346
    // TODO: implement JSONAble on SQLRowValues and Group
347
    @Override
348
    public JSONObject toJSON() {
349
        final JSONObject json = super.toJSON();
350
        if (!this.editMode.equals(EditMode.READONLY)) {
351
            if (this.editMode.equals(EditMode.CREATION)) {
352
                json.put(EDIT_MODE_JSON_KEY, 1);
353
            } else if (this.editMode.equals(EditMode.MODIFICATION)) {
354
                json.put(EDIT_MODE_JSON_KEY, 2);
355
            }
356
        }
357
        return json;
358
    }
359
 
360
    @Override
361
    public void fromJSON(final JSONObject json) {
362
        super.fromJSON(json);
363
        final int jsonEditMode = JSONConverter.getParameterFromJSON(json, EDIT_MODE_JSON_KEY, Integer.class, 3);
364
        if (jsonEditMode == 1) {
365
            this.editMode = EditMode.CREATION;
366
        } else if (jsonEditMode == 2) {
367
            this.editMode = EditMode.MODIFICATION;
368
        } else if (jsonEditMode == 3) {
369
            this.editMode = EditMode.READONLY;
370
        }
371
    }
156 ilm 372
 
373
    @Override
374
    public void writeExternal(ObjectOutput out) throws IOException {
375
        super.writeExternal(out);
376
        if (this.editMode.equals(EditMode.CREATION)) {
377
            out.writeByte(0);
378
        } else if (this.editMode.equals(EditMode.MODIFICATION)) {
379
            out.writeByte(1);
380
        } else if (this.editMode.equals(EditMode.READONLY)) {
381
            out.writeByte(2);
382
        } else {
383
            throw new IllegalStateException("unknown mode " + this.editMode);
384
        }
385
    }
386
 
387
    @Override
388
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
389
        super.readExternal(in);
390
        int mode = in.readByte();
391
        if (mode == 0) {
392
            this.editMode = EditMode.CREATION;
393
        } else if (mode == 1) {
394
            this.editMode = EditMode.MODIFICATION;
395
        } else if (mode == 2) {
396
            this.editMode = EditMode.READONLY;
397
        } else {
398
            throw new IllegalStateException("unknown mode " + mode);
399
        }
400
    }
132 ilm 401
}