OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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