OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 151 | 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
 
93 ilm 16
import org.openconcerto.sql.model.SQLRowAccessor;
17 ilm 17
import org.openconcerto.sql.model.SQLRowValues;
18
import org.openconcerto.sql.model.graph.Path;
142 ilm 19
import org.openconcerto.sql.request.ListSQLRequest;
93 ilm 20
import org.openconcerto.utils.Value;
17 ilm 21
import org.openconcerto.utils.cc.IPredicate;
22
 
23
import java.beans.PropertyChangeEvent;
24
import java.beans.PropertyChangeListener;
25
import java.sql.SQLException;
26
import java.util.ArrayList;
182 ilm 27
import java.util.Collection;
151 ilm 28
import java.util.Comparator;
17 ilm 29
import java.util.List;
93 ilm 30
import java.util.concurrent.Future;
17 ilm 31
 
32
// use SQLRowValues to allow graph
33
public abstract class SQLTableModelLinesSource {
34
 
35
    private final ITableModel model;
151 ilm 36
    private final PropertyChangeListener reqListener;
17 ilm 37
    private final List<PropertyChangeListener> listeners;
38
    private IPredicate<SQLRowValues> filter;
39
 
40
    {
41
        this.listeners = new ArrayList<PropertyChangeListener>();
42
        this.filter = null;
43
    }
44
 
45
    protected SQLTableModelLinesSource(final ITableModel model) {
46
        this.model = model;
151 ilm 47
        this.reqListener = new PropertyChangeListener() {
48
            @Override
49
            public void propertyChange(PropertyChangeEvent evt) {
50
                fireChanged(evt);
51
            }
52
        };
17 ilm 53
    }
54
 
151 ilm 55
    void live() {
56
        this.getParent().getReq().addWhereListener(this.reqListener);
57
    }
58
 
17 ilm 59
    void die() {
151 ilm 60
        this.getParent().getReq().rmWhereListener(this.reqListener);
17 ilm 61
    }
62
 
63
    public final ITableModel getModel() {
64
        return this.model;
65
    }
66
 
67
    public abstract SQLTableModelSource getParent();
68
 
142 ilm 69
    public final ListSQLRequest getUpdateQueueReq() {
70
        return this.getModel().getUpdateQ().getState().getReq();
71
    }
72
 
182 ilm 73
    public final List<ListSQLLine> getAll() {
74
        return this.get(null);
75
    }
17 ilm 76
 
77
    /**
182 ilm 78
     * Fetch up to date values from the DB.
79
     *
80
     * @param ids which rows to fetch, <code>null</code> meaning all.
81
     * @return the new values from the DB, some changes in the DB might be ignored if there's
82
     *         pending changes in this.
83
     */
84
    public abstract List<ListSQLLine> get(final Collection<? extends Number> ids);
85
 
86
    /**
93 ilm 87
     * A row in the DB has been changed, fetch its current value.
17 ilm 88
     *
89
     * @param id a valid ID of a database row.
93 ilm 90
     * @return if not {@link Value#hasValue()} the event should be ignored, otherwise the new value
91
     *         for the passed ID, <code>null</code> if it is not part of this.
17 ilm 92
     */
93 ilm 93
    public abstract Value<ListSQLLine> get(final int id);
17 ilm 94
 
151 ilm 95
    /**
96
     * Implementations should only use state of the parameters, so that this method can be
97
     * thread-safe (it is called both by the {@link UpdateQueue} and by the EDT in
98
     * {@link ITableModel}). This implementation order lines like the source {@link ListSQLRequest
99
     * request}.
100
     *
101
     * @param l1 the first line.
102
     * @param l2 the second line.
103
     * @return a negative integer, zero, or a positive integer as this object is less than, equal
104
     *         to, or greater than the specified object.
105
     * @see Comparator#compare(Object, Object)
106
     */
107
    public int compare(ListSQLLine l1, ListSQLLine l2) {
108
        return ListSQLLine.compareLikeRequest(l1, l2);
109
    }
17 ilm 110
 
151 ilm 111
    public boolean isCellEditable(ListSQLLine line, int colIndex, SQLTableModelColumn col) {
112
        return true;
113
    }
114
 
93 ilm 115
    public abstract Future<?> moveBy(final List<? extends SQLRowAccessor> rows, final int inc);
116
 
117
    // take IDs :
118
    // 1. no need to protect rows from modifications, just copy IDs
119
    // 2. for non committed rows, i.e. without DB ID and thus without SQLRow, it's easier to handle
120
    // (virtual) IDs than to use IdentitySet of SQLRowValues
121
    public abstract Future<?> moveTo(final List<? extends Number> rows, final int rowIndex);
122
 
17 ilm 123
    public final void setFilter(final IPredicate<SQLRowValues> filter) {
124
        // always fire since for now there's no other way for the caller
125
        // (ie if the meaning of filter change, it has to do setFilter(getFilter()) )
126
        this.filter = filter;
127
        this.fireChanged(new PropertyChangeEvent(this, "filter", null, this.filter));
128
    }
129
 
130
    public final IPredicate<SQLRowValues> getFilter() {
131
        return this.filter;
132
    }
133
 
134
    /**
135
     * Adds a listener to be notified when {@link #getAll()} change value.
136
     *
137
     * @param l the listener.
138
     */
139
    public final void addListener(PropertyChangeListener l) {
140
        this.listeners.add(l);
141
    }
142
 
143
    public final void rmListener(PropertyChangeListener l) {
144
        this.listeners.remove(l);
145
    }
146
 
147
    protected final void fireChanged(PropertyChangeEvent evt) {
148
        for (final PropertyChangeListener l : this.listeners)
149
            l.propertyChange(evt);
150
    }
151
 
93 ilm 152
    protected final ListSQLLine createLine(final SQLRowValues v) {
153
        return this.createLine(v, null);
17 ilm 154
    }
155
 
93 ilm 156
    /**
157
     * Create a line with the passed row.
158
     *
159
     * @param v the values.
160
     * @param passedID the {@link ListSQLLine#getID() ID} of the result, <code>null</code> meaning
161
     *        {@link SQLRowValues#getID()}.
162
     * @return a new line.
163
     * @throws IllegalArgumentException if <code>passedID</code> is <code>null</code> and
164
     *         <code>v</code> {@link SQLRowValues#hasID() has no ID}.
165
     */
166
    protected final ListSQLLine createLine(final SQLRowValues v, final Number passedID) {
17 ilm 167
        if (v == null || (this.filter != null && !this.filter.evaluateChecked(v)))
168
            return null;
93 ilm 169
        final int id;
170
        if (passedID != null) {
171
            id = passedID.intValue();
172
        } else if (v.hasID()) {
173
            id = v.getID();
174
        } else {
175
            throw new IllegalArgumentException("No ID for " + v);
176
        }
142 ilm 177
        final ListSQLLine res = new ListSQLLine(this, v, id, this.getModel().getUpdateQ().getState());
17 ilm 178
        this.lineCreated(res);
179
        return res;
180
    }
181
 
182
    /**
183
     * A new line has been created. This implementation does nothing.
184
     *
185
     * @param res the newly created line.
186
     */
187
    protected void lineCreated(ListSQLLine res) {
188
    }
189
 
93 ilm 190
    final void colsChanged(final SQLTableModelSourceState beforeState, final SQLTableModelSourceState afterState) {
191
        this.model.getUpdateQ().stateChanged(beforeState, afterState);
17 ilm 192
    }
193
 
194
    /**
195
     * Change the line <code>l</code> at the passed path with the passed values.
196
     *
197
     * @param l the line to change, eg RECEPTEUR[12].
198
     * @param path the changing path, eg RECEPTEUR.ID_LIMITEUR.
199
     * @param vals the new values, eg LIMITEUR{ID=4, DESIGNATION="dess"}.
200
     * @throws SQLException if the values cannot be commited.
201
     */
202
    public abstract void commit(ListSQLLine l, Path path, SQLRowValues vals) throws SQLException;
203
}