OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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