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 |
}
|