OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 180 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
182 ilm 4
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
17 ilm 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.view.list;
15
 
16
import org.openconcerto.sql.element.SQLElement;
93 ilm 17
import org.openconcerto.sql.model.Constraint;
17 ilm 18
import org.openconcerto.sql.model.SQLField;
177 ilm 19
import org.openconcerto.sql.model.SQLInsert;
17 ilm 20
import org.openconcerto.sql.model.SQLRow;
73 ilm 21
import org.openconcerto.sql.model.SQLRowAccessor;
67 ilm 22
import org.openconcerto.sql.model.SQLRowListRSH;
17 ilm 23
import org.openconcerto.sql.model.SQLRowValues;
174 ilm 24
import org.openconcerto.sql.model.SQLRowValuesCluster.StoreMode;
177 ilm 25
import org.openconcerto.sql.model.SQLRowValuesCluster.StoreResult;
17 ilm 26
import org.openconcerto.sql.model.SQLSelect;
93 ilm 27
import org.openconcerto.sql.model.SQLSyntax.ConstraintType;
67 ilm 28
import org.openconcerto.sql.model.SQLTable;
177 ilm 29
import org.openconcerto.sql.model.SQLUpdate;
17 ilm 30
import org.openconcerto.sql.model.UndefinedRowValuesCache;
31
import org.openconcerto.sql.model.Where;
93 ilm 32
import org.openconcerto.sql.utils.AlterTable;
90 ilm 33
import org.openconcerto.utils.CompareUtils;
67 ilm 34
import org.openconcerto.utils.ExceptionHandler;
177 ilm 35
import org.openconcerto.utils.ListMap;
17 ilm 36
import org.openconcerto.utils.OrderedSet;
37
 
38
import java.math.BigDecimal;
39
import java.sql.SQLException;
40
import java.util.ArrayList;
93 ilm 41
import java.util.Arrays;
17 ilm 42
import java.util.Collection;
43
import java.util.HashMap;
93 ilm 44
import java.util.HashSet;
17 ilm 45
import java.util.List;
46
import java.util.Map;
93 ilm 47
import java.util.Set;
17 ilm 48
 
49
import javax.swing.SwingUtilities;
50
import javax.swing.event.EventListenerList;
51
import javax.swing.event.TableModelEvent;
52
import javax.swing.event.TableModelListener;
53
import javax.swing.table.AbstractTableModel;
54
 
55
public class RowValuesTableModel extends AbstractTableModel {
65 ilm 56
    // modification of rowValues MUST be done in AWT EDT
67 ilm 57
    // methods that perform requests, MUST use the runnableQueue
58
    // synchronized is used to protect list access
65 ilm 59
    private List<SQLRowValues> rowValues = new ArrayList<SQLRowValues>();
17 ilm 60
 
61
    private OrderedSet<TableModelListener> tableModelListeners = new OrderedSet<TableModelListener>();
62
 
63
    protected SQLElement element;
64
 
65
    private int nbColumn;
66
 
67
    private List<SQLTableElement> list; // Liste de SQLTableElement
65 ilm 68
    private Map<String, Integer> mapColumnField = new HashMap<String, Integer>();
17 ilm 69
 
73 ilm 70
    private List<SQLField> requiredFields;
71
 
17 ilm 72
    private SQLField requiredField, validationField;
73
 
65 ilm 74
    private SQLRowValues defautRow;
75
    private List<SQLRowValues> rowValuesDeleted = new ArrayList<SQLRowValues>();
17 ilm 76
 
77
    private boolean editable = true;
78
 
83 ilm 79
    private Where fillWhere;
80
 
17 ilm 81
    public RowValuesTableModel() {
82
 
83
    }
84
 
85
    public RowValuesTableModel(final SQLElement e, final List<SQLTableElement> list, SQLField validField) {
86
        this(e, list, validField, true);
87
    }
88
 
89
    public RowValuesTableModel(final SQLElement e, final List<SQLTableElement> list, SQLField validField, boolean addDefault, SQLRowValues rowParDefaut) {
90
        this(e, list, validField, addDefault, rowParDefaut, null);
91
 
92
    }
93
 
94
    public RowValuesTableModel(final SQLElement e, final List<SQLTableElement> list, SQLField validField, boolean addDefault, SQLRowValues rowParDefaut, SQLField validationField) {
95
        init(e, list, validField, addDefault, rowParDefaut, validationField);
96
 
97
    }
98
 
99
    public RowValuesTableModel(final SQLElement e, final List<SQLTableElement> list, SQLField validField, boolean addDefault) {
100
        this(e, list, validField, addDefault, null);
101
    }
102
 
103
    protected void init(final SQLElement e, final List<SQLTableElement> list, SQLField validField, boolean addDefault, SQLRowValues rowParDefaut) {
104
        init(e, list, validField, addDefault, rowParDefaut, null);
105
    }
106
 
107
    /**
108
     * @param e
109
     * @param list
110
     * @param validField
111
     * @param addDefault
112
     * @param rowParDefaut
113
     */
114
    protected void init(final SQLElement e, final List<SQLTableElement> list, SQLField validField, boolean addDefault, SQLRowValues rowParDefaut, SQLField validationField) {
115
        this.element = e;
116
        this.requiredField = validField;
73 ilm 117
        this.requiredFields = new ArrayList<SQLField>();
118
 
119
        this.requiredFields.add(validField);
17 ilm 120
        this.validationField = validationField;
121
        this.list = list;
65 ilm 122
        this.nbColumn = list.size();
17 ilm 123
 
124
        if (rowParDefaut != null) {
65 ilm 125
            this.defautRow = rowParDefaut;
17 ilm 126
        } else {
65 ilm 127
            this.defautRow = new SQLRowValues(UndefinedRowValuesCache.getInstance().getDefaultRowValues(e.getTable()));
17 ilm 128
        }
129
 
130
        // rowParDefaut
131
        if (addDefault) {
80 ilm 132
            final SQLRowValues row = new SQLRowValues(this.defautRow);
133
            final BigDecimal maxOrder = RowValuesTableModel.this.element.getTable().getMaxOrder();
134
            row.put(RowValuesTableModel.this.element.getTable().getOrderField().getName(), maxOrder.add(BigDecimal.ONE));
135
            RowValuesTableModel.this.rowValues.add(row);
65 ilm 136
        }
17 ilm 137
    }
138
 
83 ilm 139
    public void setFillWhere(Where fillWhere) {
140
        this.fillWhere = fillWhere;
141
    }
142
 
73 ilm 143
    public void addRequiredField(SQLField f) {
144
        this.requiredFields.add(f);
145
    }
146
 
182 ilm 147
    public SQLField getValidationField() {
148
        return this.validationField;
149
    }
150
 
28 ilm 151
    public SQLRowValues getDefaultRowValues() {
65 ilm 152
        return this.defautRow;
28 ilm 153
    }
154
 
17 ilm 155
    public synchronized void addColumn(SQLTableElement e) {
156
        this.nbColumn++;
157
        this.list.add(e);
158
    }
159
 
180 ilm 160
    public void setValidationField(SQLField validationField) {
161
        this.validationField = validationField;
162
    }
163
 
17 ilm 164
    public synchronized int getColumnCount() {
165
        return this.nbColumn;
166
    }
167
 
67 ilm 168
    public int getRowCount() {
169
        checkEDT();
17 ilm 170
        return this.rowValues.size();
171
    }
172
 
173
    public boolean isCellEditable(int rowIndex, int columnIndex) {
174
        if (!this.editable)
175
            return false;
176
 
177
        SQLTableElement elt = this.list.get(columnIndex);
178
        boolean validate = false;
179
        boolean fieldValidate = false;
180
        if (this.validationField != null) {
181
            fieldValidate = elt.getField().getName().equalsIgnoreCase(this.validationField.getName());
182
            validate = this.getRowValuesAt(rowIndex).getBoolean(this.validationField.getName());
183
        }
184
        if (validate && fieldValidate) {
132 ilm 185
            return this.list.get(columnIndex).isCellEditable(this.getRowValuesAt(rowIndex), rowIndex, columnIndex);
17 ilm 186
        } else {
132 ilm 187
            return (!validate) && this.list.get(columnIndex).isCellEditable(this.getRowValuesAt(rowIndex), rowIndex, columnIndex);
17 ilm 188
        }
189
    }
190
 
191
    public synchronized Class<?> getColumnClass(int columnIndex) {
192
        return this.list.get(columnIndex).getElementClass();
193
    }
194
 
195
    public Object getValueAt(int rowIndex, int columnIndex) {
67 ilm 196
        checkEDT();
65 ilm 197
        final Object result;
17 ilm 198
 
199
        if (rowIndex >= this.rowValues.size()) {
65 ilm 200
            System.err.println("RowValuesTableModel: get(" + rowIndex + "," + columnIndex + ") rowIndex>" + this.rowValues.size());
17 ilm 201
            Thread.dumpStack();
65 ilm 202
            result = new Integer(0);
203
        } else {
204
            SQLRowValues val = this.rowValues.get(rowIndex);
205
            SQLTableElement sqlTableElem = this.list.get(columnIndex);
132 ilm 206
            Object storedObject = val.getObject(sqlTableElem.getRowField());
65 ilm 207
            result = sqlTableElem.getValueFrom(val);
132 ilm 208
            if (sqlTableElem.getElementClass() != null && Number.class.isAssignableFrom(sqlTableElem.getElementClass()) && !CompareUtils.equals(result, storedObject)) {
209
                fireTableDataChanged();
210
            }
211
 
17 ilm 212
        }
213
 
214
        return result;
215
    }
216
 
67 ilm 217
    private void checkEDT() {
65 ilm 218
        if (!SwingUtilities.isEventDispatchThread())
219
            Thread.dumpStack();
67 ilm 220
    }
221
 
222
    public void putValue(Object value, int rowIndex, String fieldName) {
93 ilm 223
        putValue(value, rowIndex, fieldName, false);
224
    }
225
 
226
    public void putValue(Object value, int rowIndex, String fieldName, boolean forcedFire) {
67 ilm 227
        checkEDT();
65 ilm 228
        final SQLRowValues rowVal = this.rowValues.get(rowIndex);
73 ilm 229
        Object oldValue = rowVal.getObject(fieldName);
93 ilm 230
        if (!forcedFire) {
231
            if (oldValue == value) {
232
                return;
233
            }
234
            if (oldValue != null && oldValue.equals(value)) {
235
                return;
236
            }
73 ilm 237
        }
17 ilm 238
        rowVal.put(fieldName, value);
239
        for (SQLTableElement sqlTableElem : this.list) {
182 ilm 240
            if (sqlTableElem.getField().getName().equals(fieldName)) {
241
                sqlTableElem.fireModification(rowVal);
242
            }
17 ilm 243
        }
244
        fireTableModelModified(rowIndex);
245
    }
246
 
247
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
67 ilm 248
        checkEDT();
17 ilm 249
        if (!this.editable)
250
            return;
67 ilm 251
        if (this.list.size() <= columnIndex) {
252
            return;
253
        }
73 ilm 254
 
255
        Object oldValue = getValueAt(rowIndex, columnIndex);
256
        if (aValue == oldValue) {
257
            return;
258
        }
259
        if (oldValue != null && oldValue.equals(aValue)) {
260
            return;
261
        }
83 ilm 262
        try {
263
            SQLTableElement sqlTableElem = this.list.get(columnIndex);
73 ilm 264
 
83 ilm 265
            SQLRowValues rowVal = this.rowValues.get(rowIndex);
266
            Object realVal = sqlTableElem.convertEditorValueToModel(aValue, rowVal);
267
            if (realVal == null || realVal.getClass() == this.getColumnClass(columnIndex)) {
268
                sqlTableElem.setValueFrom(rowVal, realVal);
269
                fireTableChanged(new TableModelEvent(this, rowIndex, rowIndex, columnIndex));
270
            } else {
271
                System.err.println("RowValuesTableModel:setValueAt:" + realVal + "(" + realVal.getClass() + ") at (row:" + rowIndex + "/col:" + columnIndex + ") column class : "
272
                        + this.getColumnClass(columnIndex));
273
                Thread.dumpStack();
274
            }
275
        } catch (Exception e) {
276
            // can append when stop editing occur while removing a line
277
            e.printStackTrace();
17 ilm 278
        }
279
    }
280
 
281
    /**
282
     *
283
     */
67 ilm 284
    public void dumpValues() {
17 ilm 285
        for (int i = 0; i < this.rowValues.size(); i++) {
286
            SQLRowValues val = this.rowValues.get(i);
287
            System.out.println("Item" + i + ":" + val);
288
        }
289
    }
290
 
291
    public String getColumnName(int columnIndex) {
292
        SQLTableElement sqlTableElem = this.list.get(columnIndex);
293
        return sqlTableElem.getColumnName();
294
    }
295
 
296
    /**
297
     * Valider les modifications dans la base
298
     */
299
    public void commitData() {
177 ilm 300
        commitData(false);
301
    }
302
 
303
    /**
304
     * Valider les modifications dans la base
305
     */
306
    public void commitData(boolean useMultipleInsertUpdate) {
67 ilm 307
        checkEDT();
308
        final List<SQLRowValues> rowsToCommmit = new ArrayList<SQLRowValues>();
309
        rowsToCommmit.addAll(this.rowValues);
73 ilm 310
        try {
93 ilm 311
            final SQLTable table = getDefaultRowValues().getTable();
312
            // Remove constraint on ORDRE for private
313
            final Constraint constraint = table.getConstraint(ConstraintType.UNIQUE, Arrays.asList(table.getOrderField().getName()));
314
            if (constraint != null) {
315
                final String req = new AlterTable(table).dropConstraint(constraint.getName()).asString();
316
                table.getDBSystemRoot().getDataSource().execute(req);
317
                table.fetchFields();
318
                table.getSchema().updateVersion();
319
            }
177 ilm 320
 
93 ilm 321
            BigDecimal o = table.getMaxOrder(Boolean.FALSE);
73 ilm 322
            final int size = rowsToCommmit.size();
177 ilm 323
 
324
            if (useMultipleInsertUpdate) {
325
                List<SQLUpdate> updates = new ArrayList<>();
326
                ListMap<List<SQLField>, SQLInsert> mapInsertByFields = new ListMap<>();
327
                ListMap<List<SQLField>, SQLRowValues> mapInsertRowValues = new ListMap<>();
328
 
329
                for (int i = 0; i < size; i++) {
330
                    final SQLRowValues r = rowsToCommmit.get(i);
331
                    r.put(r.getTable().getOrderField().getFieldName(), o.add(new BigDecimal(i + 1)));
332
                    if (r.hasID()) {
333
                        SQLUpdate up = new SQLUpdate(new Where(table.getKey(), "=", r.getID()));
334
                        up.importValuesFrom(r);
335
                        updates.add(up);
336
                    } else {
337
                        SQLInsert insert = new SQLInsert();
338
                        insert.importValuesFrom(r);
339
                        List<SQLField> fields = insert.getFields();
340
                        mapInsertByFields.add(fields, insert);
341
                        mapInsertRowValues.add(fields, r);
342
                    }
343
                }
344
                if (!mapInsertByFields.isEmpty()) {
345
 
346
                    for (List<SQLField> fieldSize : mapInsertByFields.keySet()) {
347
                        List<Number> ids = SQLInsert.executeSimilarInserts(table.getDBSystemRoot(), mapInsertByFields.get(fieldSize), true);
348
                        List<SQLRowValues> insertsRowValues = mapInsertRowValues.get(fieldSize);
349
                        if (ids.size() == insertsRowValues.size()) {
350
                            for (int i = 0; i < ids.size(); i++) {
351
                                final SQLRowValues r = insertsRowValues.get(i);
352
                                r.setID(ids.get(i));
353
                            }
354
                        }
355
 
356
                    }
357
 
358
                }
359
                if (!updates.isEmpty()) {
360
                    SQLUpdate.executeMultipleWithBatch(table.getDBSystemRoot(), updates);
361
                }
362
                table.fireTableModified(-1);
363
            } else {
364
                for (int i = 0; i < size; i++) {
365
                    final SQLRowValues r = rowsToCommmit.get(i);
366
                    r.put(r.getTable().getOrderField().getFieldName(), o.add(new BigDecimal(i + 1)));
367
                    final StoreResult store = r.getGraph().store(StoreMode.COMMIT, false);
368
                    final SQLRow row = store.getStoredRow(r);
369
                    r.setID(row.getIDNumber());
370
                }
371
 
17 ilm 372
            }
73 ilm 373
        } catch (SQLException e) {
374
            ExceptionHandler.handle("Unable to commit rows", e);
375
        }
177 ilm 376
 
17 ilm 377
    }
378
 
379
    public void addTableModelListener(TableModelListener l) {
380
        this.tableModelListeners.add(l);
381
    }
382
 
383
    public void removeTableModelListener(TableModelListener l) {
384
        this.tableModelListeners.remove(l);
385
    }
386
 
387
    public void fireTableModelModified(int line) {
83 ilm 388
        checkEDT();
17 ilm 389
        this.fireTableRowsUpdated(line, line);
390
 
391
    }
392
 
393
    public int getColumnForField(String to) {
394
        if (this.mapColumnField.get(to) == null) {
395
 
396
            for (int columnIndex = 0; columnIndex < this.list.size(); columnIndex++) {
397
                SQLTableElement sqlTableElem = this.list.get(columnIndex);
398
                if (sqlTableElem.getField() != null) {
399
                    if (sqlTableElem.getField().getName().equalsIgnoreCase(to)) {
400
                        this.mapColumnField.put(to, columnIndex);
401
                        return columnIndex;
402
                    }
403
                }
404
            }
405
            this.mapColumnField.put(to, -1);
406
            return -1;
407
        } else {
408
            return this.mapColumnField.get(to);
409
        }
410
    }
411
 
67 ilm 412
    public void addNewRowAt(final int index) {
413
        checkEDT();
414
        if (index > getRowCount()) {
415
            throw new IllegalArgumentException(index + " > row count: " + getRowCount());
416
        } else if (index < 0) {
417
            throw new IllegalArgumentException(index + " <0");
418
        }
17 ilm 419
 
73 ilm 420
        final SQLRowValues newRowParDefaut = new SQLRowValues(RowValuesTableModel.this.defautRow);
132 ilm 421
        if (index > 0 && index < getRowCount() && newRowParDefaut.getTable().contains("NIVEAU")) {
422
            newRowParDefaut.put("NIVEAU", this.rowValues.get(index - 1).getObject("NIVEAU"));
423
        }
83 ilm 424
        RowValuesTableModel.this.rowValues.add(index, newRowParDefaut);
17 ilm 425
 
83 ilm 426
        final int size = RowValuesTableModel.this.tableModelListeners.size();
427
        for (int i = 0; i < size; i++) {
428
            final TableModelListener l = RowValuesTableModel.this.tableModelListeners.get(i);
429
            l.tableChanged(new TableModelEvent(RowValuesTableModel.this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
430
        }
17 ilm 431
 
432
    }
433
 
93 ilm 434
    public void addRowAt(final int index, SQLRowValues rowVals) {
435
        checkEDT();
436
        if (index > getRowCount()) {
437
            throw new IllegalArgumentException(index + " > row count: " + getRowCount());
438
        } else if (index < 0) {
439
            throw new IllegalArgumentException(index + " <0");
440
        }
441
 
442
        RowValuesTableModel.this.rowValues.add(index, rowVals);
443
 
444
        final int size = RowValuesTableModel.this.tableModelListeners.size();
445
        for (int i = 0; i < size; i++) {
446
            final TableModelListener l = RowValuesTableModel.this.tableModelListeners.get(i);
447
            l.tableChanged(new TableModelEvent(RowValuesTableModel.this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
448
        }
449
 
450
    }
451
 
17 ilm 452
    /**
453
     * Suppression d'une ligne de la table
454
     *
455
     * @param index index de la ligne
456
     */
67 ilm 457
    public void removeRowAt(final int index) {
458
        checkEDT();
83 ilm 459
        if (index < 0) {
17 ilm 460
            return;
83 ilm 461
        }
462
        final SQLRowValues removedLine = this.rowValues.remove(index);
463
        this.rowValuesDeleted.add(removedLine);
67 ilm 464
        fireTableRowsDeleted(index, index);
17 ilm 465
    }
466
 
467
    /**
468
     * Suppression de plusieurs ligne de la table
469
     *
470
     * @param index tableau des index de ligne à supprimer
471
     */
67 ilm 472
    public void removeRowsAt(final int[] index) {
473
        checkEDT();
17 ilm 474
        if (index.length <= 0)
475
            return;
476
 
67 ilm 477
        final List<SQLRowValues> rowVals = new ArrayList<SQLRowValues>(index.length);
478
        for (int i : index) {
479
            final SQLRowValues rowValues2 = RowValuesTableModel.this.rowValues.get(i);
480
            rowVals.add(rowValues2);
481
            RowValuesTableModel.this.rowValuesDeleted.add(rowValues2);
482
        }
93 ilm 483
 
484
        // Ne pas utiliser removeAll, supprime toutes les lignes equals
485
        // RowValuesTableModel.this.rowValues.removeAll(rowVals);
486
        for (SQLRowValues sqlRowValues2Remove : rowVals) {
487
            for (int i = 0; i < getRowCount(); i++) {
488
                SQLRowValues rowValsList = RowValuesTableModel.this.rowValues.get(i);
489
                if (rowValsList == sqlRowValues2Remove) {
490
                    RowValuesTableModel.this.rowValues.remove(i);
491
                    break;
492
                }
493
            }
494
        }
67 ilm 495
        fireTableDataChanged();
17 ilm 496
 
497
    }
498
 
67 ilm 499
    public void addNewRow() {
17 ilm 500
        addNewRowAt(getRowCount());
501
    }
502
 
503
    public boolean isLastRowValid() {
504
        return isRowValid(this.rowValues.size() - 1);
505
    }
506
 
507
    public boolean isRowValid(int index) {
67 ilm 508
        checkEDT();
17 ilm 509
        if (this.rowValues.size() == 0)
510
            return true;
511
 
512
        if (index < 0 || index >= this.rowValues.size()) {
513
            return false;
514
        }
515
 
516
        SQLRowValues row = this.rowValues.get(index);
517
 
73 ilm 518
        boolean valid = true;
519
        for (SQLField f : this.requiredFields) {
520
            if (f.isKey()) {
521
                valid &= !row.isForeignEmpty(f.getName());
522
            } else {
523
                final Object object = row.getObject(f.getName());
524
                valid &= object != null && object.toString().trim().length() > 0;
525
            }
526
            if (!valid) {
527
                break;
528
            }
17 ilm 529
        }
73 ilm 530
        return valid;
17 ilm 531
    }
532
 
533
    public boolean isValidated() {
534
        boolean b = true;
535
        for (int i = 0; i < getRowCount(); i++) {
536
            b &= isRowValid(i);
537
        }
538
        return b;
539
    }
540
 
541
    public final List<SQLTableElement> getList() {
542
        return this.list;
543
    }
544
 
545
    public void updateField(String field, SQLRowValues rowVals, String fieldCondition) {
67 ilm 546
        checkEDT();
17 ilm 547
        if (rowVals != null) {
548
            int stop = this.rowValues.size();
65 ilm 549
 
550
            // FIXME check à faire sur l'ensemble des rows avec la methode isValid(). Quand
551
            // RowValuesTable deviendra un RowItemView.
552
            // if (!isLastRowValid()) {
553
            // stop--;
554
            // }
17 ilm 555
            int id = rowVals.getID();
556
 
557
            for (int i = 0; i < stop; i++) {
558
 
559
                SQLRowValues r = this.rowValues.get(i);
560
 
561
                if (fieldCondition != null) {
562
                    Object o = r.getObject(fieldCondition);
563
                    if (o != null && ((Boolean) o)) {
564
                        if (id != SQLRow.NONEXISTANT_ID) {
565
                            r.put(field, id);
566
                        } else {
567
                            r.put(field, rowVals);
568
                        }
569
                    } else {
570
                        r.put(field, 1);
571
                    }
572
                } else {
573
                    if (id != SQLRow.NONEXISTANT_ID) {
574
                        r.put(field, id);
575
                    } else {
576
                        r.put(field, rowVals);
577
                    }
578
                }
579
            }
83 ilm 580
            // FIXME : must be done in commit not here
17 ilm 581
            List<SQLRowValues> l = new ArrayList<SQLRowValues>(this.rowValuesDeleted);
93 ilm 582
            Set<SQLRowValues> toArchive = new HashSet<SQLRowValues>();
17 ilm 583
            for (int i = 0; i < l.size(); i++) {
584
                SQLRowValues rowVals2 = l.get(i);
585
                int idRow = rowVals2.getID();
586
                if (idRow != SQLRow.NONEXISTANT_ID) {
93 ilm 587
                    toArchive.add(rowVals2);
17 ilm 588
                } else {
589
                    rowVals2.putEmptyLink(field);
590
                }
591
            }
65 ilm 592
            this.rowValuesDeleted.clear();
93 ilm 593
            try {
594
                this.element.archive(toArchive);
595
            } catch (SQLException e) {
596
                throw new IllegalStateException("Unable to archive rows : " + toArchive, e);
597
            }
598
 
17 ilm 599
            if (id != SQLRow.NONEXISTANT_ID) {
600
                this.commitData();
601
            }
602
        }
603
    }
604
 
605
    public void updateField(String field, SQLRowValues rowVals) {
606
        updateField(field, rowVals, null);
607
    }
608
 
609
    public void updateField(String field, int id) {
610
        updateField(field, id, null);
611
    }
612
 
613
    public void updateField(String field, int id, String fieldCondition) {
614
        if (id > 0) {
615
            updateField(field, this.element.getTable().getForeignTable(field).getRow(id).createUpdateRow(), fieldCondition);
616
        }
617
    }
618
 
619
    public void insertFrom(String field, int id) {
620
        insertFrom(field, id, SQLRow.NONEXISTANT_ID);
621
    }
622
 
623
    public void insertFrom(final String field, final int id, final int exceptID) {
67 ilm 624
        checkEDT();
17 ilm 625
        if (id > 0) {
626
 
93 ilm 627
            SQLSelect sel = new SQLSelect();
628
            final SQLTable table = RowValuesTableModel.this.element.getTable();
629
            sel.addSelectStar(table);
630
            Where w = new Where(table.getField(field), "=", id);
631
            w = w.and(new Where(table.getKey(), "!=", exceptID));
632
            if (fillWhere != null) {
633
                w = w.and(fillWhere);
634
            }
635
            sel.setWhere(w);
636
            sel.addFieldOrder(table.getOrderField());
17 ilm 637
 
93 ilm 638
            final List<SQLRow> listOfRows = SQLRowListRSH.execute(sel);
17 ilm 639
 
93 ilm 640
            RowValuesTableModel.this.rowValues.clear();
641
            final int size = listOfRows.size();
642
            for (int i = 0; i < size; i++) {
643
                SQLRow sqlRow = listOfRows.get(i);
644
                SQLRowValues row = sqlRow.createUpdateRow();
645
                RowValuesTableModel.this.rowValues.add(row);
646
            }
647
            fireTableModelModified(RowValuesTableModel.this.rowValues.size());
17 ilm 648
 
649
        }
90 ilm 650
 
17 ilm 651
    }
652
 
90 ilm 653
    public void insertFrom(final SQLRowAccessor rowVals) {
654
        insertFrom(rowVals, null);
655
    }
656
 
657
    public void insertFrom(final SQLRowAccessor rowVals, final SQLField referentField) {
658
        insertFrom(rowVals, referentField, null, null);
659
    }
660
 
83 ilm 661
    // Remplit la table à partir de la SQLRow parente
90 ilm 662
    public void insertFrom(final SQLRowAccessor rowVals, final SQLField referentField, final SQLField fieldWhere, final Object value) {
17 ilm 663
        if (!SwingUtilities.isEventDispatchThread()) {
664
            Thread.dumpStack();
665
        }
666
        if (rowVals != null) {
667
 
93 ilm 668
            final List<SQLRowValues> newRows = new ArrayList<SQLRowValues>();
17 ilm 669
 
177 ilm 670
            if (rowVals.hasID() && !rowVals.isUndefined() && rowVals.getID() != SQLRow.NONEXISTANT_ID) {
93 ilm 671
                SQLRow row = rowVals.getTable().getRow(rowVals.getID());
672
                List<SQLRow> rowSet;
673
                if (referentField == null) {
674
                    rowSet = row.getReferentRows(RowValuesTableModel.this.element.getTable());
675
                } else {
676
                    rowSet = row.getReferentRows(referentField);
677
                }
678
                for (SQLRow row2 : rowSet) {
679
                    if (fieldWhere == null || CompareUtils.equals(row2.getObject(fieldWhere.getName()), value)) {
680
                        SQLRowValues rowVals2 = new SQLRowValues(RowValuesTableModel.this.element.getTable());
681
                        rowVals2.loadAbsolutelyAll(row2);
682
                        newRows.add(rowVals2);
683
                    }
684
                }
17 ilm 685
 
93 ilm 686
            } else {
687
                final Collection<? extends SQLRowAccessor> colRows;
688
                if (referentField == null) {
689
                    colRows = rowVals.getReferentRows(RowValuesTableModel.this.element.getTable());
690
                } else {
691
                    colRows = rowVals.getReferentRows(referentField);
692
                }
693
                for (SQLRowAccessor rowValues : colRows) {
694
                    if (fieldWhere == null || CompareUtils.equals(rowValues.getObject(fieldWhere.getName()), value)) {
695
                        newRows.add(rowValues.asRowValues());
17 ilm 696
                    }
697
                }
93 ilm 698
            }
699
 
700
            RowValuesTableModel.this.rowValues.clear();
701
            RowValuesTableModel.this.rowValues.addAll(newRows);
702
            fireTableModelModified(RowValuesTableModel.this.rowValues.size());
703
 
17 ilm 704
        }
705
    }
706
 
707
    public void addRow(SQLRowValues row) {
93 ilm 708
        checkEDT();
17 ilm 709
        addRow(row, true);
710
    }
711
 
83 ilm 712
    public void addRow(final SQLRowValues row, final boolean fireModified) {
93 ilm 713
        checkEDT();
83 ilm 714
        final List<SQLRowValues> rows = new ArrayList<SQLRowValues>(1);
715
        rows.add(row);
182 ilm 716
        addRows(rows, fireModified);
83 ilm 717
    }
718
 
80 ilm 719
    public void submit(Runnable r) {
93 ilm 720
        checkEDT();
721
        r.run();
80 ilm 722
    }
723
 
83 ilm 724
    public void addRows(final List<SQLRowValues> rows, final boolean fireModified) {
67 ilm 725
        checkEDT();
83 ilm 726
        if (rows.isEmpty()) {
727
            return;
728
        }
17 ilm 729
 
93 ilm 730
        addRowsSync(rows, fireModified);
17 ilm 731
 
732
    }
733
 
734
    public void clearRows() {
83 ilm 735
        checkEDT();
67 ilm 736
        final int size = RowValuesTableModel.this.rowValues.size();
737
        if (size > 0) {
738
            RowValuesTableModel.this.rowValues.clear();
739
            fireTableRowsDeleted(0, size - 1);
740
        }
65 ilm 741
 
17 ilm 742
    }
743
 
67 ilm 744
    public synchronized SQLTableElement getSQLTableElementAt(int columnIndex) {
93 ilm 745
        checkEDT();
17 ilm 746
        if (columnIndex >= 0 && columnIndex < this.list.size()) {
747
            return this.list.get(columnIndex);
748
        } else {
749
            return null;
750
        }
751
    }
752
 
67 ilm 753
    public synchronized int getColumnIndexForElement(SQLTableElement e) {
93 ilm 754
        checkEDT();
17 ilm 755
        for (int columnIndex = 0; columnIndex < this.list.size(); columnIndex++) {
756
            SQLTableElement sqlTableElem = this.list.get(columnIndex);
757
            if (sqlTableElem.equals(e)) {
758
                return columnIndex;
759
            }
760
        }
761
        return -1;
762
    }
763
 
764
    public SQLRowValues getRowValuesAt(int rowIndex) {
67 ilm 765
        checkEDT();
17 ilm 766
        return this.rowValues.get(rowIndex);
767
    }
768
 
769
    public final int id2index(int id) {
83 ilm 770
        checkEDT();
17 ilm 771
        for (int i = 0; i < this.getRowCount(); i++) {
772
            if (this.getRowValuesAt(i).getID() == id)
773
                return i;
774
        }
775
        return -1;
776
    }
777
 
93 ilm 778
    public final int row2index(SQLRowAccessor row) {
83 ilm 779
        checkEDT();
93 ilm 780
        return this.rowValues.indexOf(row);
83 ilm 781
    }
782
 
17 ilm 783
    public void fireTableChanged(TableModelEvent event) {
67 ilm 784
        checkEDT();
17 ilm 785
        for (int i = 0; i < this.tableModelListeners.size(); i++) {
786
            TableModelListener l = this.tableModelListeners.get(i);
787
            l.tableChanged(event);
788
        }
789
    }
790
 
791
    /**
792
     * Notifies all listeners that all cell values in the table's rows may have changed. The number
793
     * of rows may also have changed and the <code>JTable</code> should redraw the table from
794
     * scratch. The structure of the table (as in the order of the columns) is assumed to be the
795
     * same.
796
     *
797
     * @see TableModelEvent
798
     * @see EventListenerList
799
     * @see javax.swing.JTable#tableChanged(TableModelEvent)
800
     */
801
    public void fireTableDataChanged() {
802
        fireTableChanged(new TableModelEvent(this));
803
    }
804
 
805
    /**
806
     * Notifies all listeners that the table's structure has changed. The number of columns in the
807
     * table, and the names and types of the new columns may be different from the previous state.
808
     * If the <code>JTable</code> receives this event and its
809
     * <code>autoCreateColumnsFromModel</code> flag is set it discards any table columns that it had
810
     * and reallocates default columns in the order they appear in the model. This is the same as
811
     * calling <code>setModel(TableModel)</code> on the <code>JTable</code>.
812
     *
813
     * @see TableModelEvent
814
     * @see EventListenerList
815
     */
816
    public void fireTableStructureChanged() {
817
        fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
818
    }
819
 
820
    /**
821
     * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>, inclusive,
822
     * have been inserted.
823
     *
824
     * @param firstRow the first row
825
     * @param lastRow the last row
826
     *
827
     * @see TableModelEvent
828
     * @see EventListenerList
829
     *
830
     */
831
    public void fireTableRowsInserted(int firstRow, int lastRow) {
832
        fireTableChanged(new TableModelEvent(this, firstRow, lastRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
833
    }
834
 
835
    /**
836
     * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>, inclusive,
837
     * have been updated.
838
     *
839
     * @param firstRow the first row
840
     * @param lastRow the last row
841
     *
842
     * @see TableModelEvent
843
     * @see EventListenerList
844
     */
845
    public void fireTableRowsUpdated(int firstRow, int lastRow) {
846
        fireTableChanged(new TableModelEvent(this, firstRow, lastRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.UPDATE));
847
    }
848
 
849
    /**
850
     * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code>, inclusive,
851
     * have been deleted.
852
     *
853
     * @param firstRow the first row
854
     * @param lastRow the last row
855
     *
856
     * @see TableModelEvent
857
     * @see EventListenerList
858
     */
859
    public void fireTableRowsDeleted(int firstRow, int lastRow) {
860
        fireTableChanged(new TableModelEvent(this, firstRow, lastRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
861
    }
862
 
863
    /**
864
     * Notifies all listeners that the value of the cell at <code>[row, column]</code> has been
865
     * updated.
866
     *
867
     * @param row row of cell which has been updated
868
     * @param column column of cell which has been updated
869
     * @see TableModelEvent
870
     * @see EventListenerList
871
     */
872
    public void fireTableCellUpdated(int row, int column) {
873
        fireTableChanged(new TableModelEvent(this, row, row, column));
874
    }
875
 
876
    /**
877
     * Déplacer une ligne
878
     *
879
     * @param rowIndex ligne à déplacer
880
     * @param inc incrémentation +1 ou -1
881
     * @return le nouvel index
882
     */
883
    public int moveBy(int rowIndex, int inc) {
67 ilm 884
        checkEDT();
17 ilm 885
        int destIndex = rowIndex + inc;
886
 
887
        // On vérifie que l'on reste dans le tableau
888
        if (rowIndex >= 0 && destIndex >= 0) {
889
            if (rowIndex < this.rowValues.size() && destIndex < this.rowValues.size()) {
890
                SQLRowValues rowValues1 = this.rowValues.get(rowIndex);
891
                SQLRowValues rowValues2 = this.rowValues.get(destIndex);
892
                this.rowValues.set(rowIndex, rowValues2);
893
                this.rowValues.set(destIndex, rowValues1);
894
                this.fireTableRowsUpdated(rowIndex, destIndex);
895
                this.fireTableDataChanged();
896
            }
897
        }
898
        return destIndex;
899
    }
900
 
67 ilm 901
    public List<SQLRowValues> getCopyOfValues() {
902
        checkEDT();
903
        List<SQLRowValues> vals = new ArrayList<SQLRowValues>(this.rowValues.size());
904
        for (SQLRowValues sqlRowValues : this.rowValues) {
905
            vals.add(sqlRowValues.asRowValues());
906
        }
907
        return vals;
908
    }
909
 
17 ilm 910
    /**
911
     * Rendre une colonne éditable ou nom
912
     *
913
     * @param b
914
     * @param column
915
     */
916
    public void setEditable(boolean b, int column) {
93 ilm 917
        checkEDT();
17 ilm 918
        this.list.get(column).setEditable(b);
919
    }
920
 
921
    public void setEditable(boolean b) {
922
        this.editable = b;
923
 
924
    }
925
 
926
    public SQLElement getSQLElement() {
927
        return this.element;
928
    }
929
 
930
    public SQLField getRequiredField() {
931
        return this.requiredField;
932
    }
73 ilm 933
 
934
    public List<SQLField> getRequiredsField() {
935
        return this.requiredFields;
936
    }
83 ilm 937
 
938
    public void addRowsSync(final List<SQLRowValues> rows, final boolean fireModified) {
939
        checkEDT();
940
        if (rows.isEmpty()) {
941
            return;
942
        }
943
        RowValuesTableModel.this.rowValues.addAll(rows);
944
        if (fireModified) {
945
            for (SQLRowValues row : rows) {
946
                for (SQLTableElement sqlTableElem : RowValuesTableModel.this.list) {
947
                    sqlTableElem.fireModification(row);
948
                }
949
            }
950
            fireTableRowsInserted(RowValuesTableModel.this.rowValues.size() - rows.size(), RowValuesTableModel.this.rowValues.size() - 1);
951
        }
952
    }
17 ilm 953
}