1
2
3
4
5 package org.rcfaces.core.internal.tools;
6
7 import java.io.Serializable;
8 import java.util.Arrays;
9 import java.util.HashSet;
10 import java.util.Set;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.rcfaces.core.model.AbstractIndexesModel;
15 import org.rcfaces.core.model.ICommitableObject;
16 import org.rcfaces.core.model.IIndexesModel;
17
18
19
20
21
22 public class ArrayIndexesModel extends AbstractIndexesModel implements
23 Serializable, ICommitableObject {
24 private static final String REVISION = "$Revision: 1.18 $";
25
26 private static final long serialVersionUID = 7393822820762985697L;
27
28 private static final Log LOG = LogFactory.getLog(ArrayIndexesModel.class);
29
30 protected static final int[] EMPTY_SELECTION = new int[0];
31
32 private static final boolean VERIFY_GARBAGE = LOG.isDebugEnabled();
33 static {
34 if (VERIFY_GARBAGE) {
35 LOG.info("Verify GARBAGE enabled");
36 }
37 }
38
39 private int selectionIndexes[] = EMPTY_SELECTION;
40
41 private int lastPos = 0;
42
43 private int count = 0;
44
45 private boolean garbaged = true;
46
47 private boolean commited;
48
49 public ArrayIndexesModel() {
50 }
51
52 public ArrayIndexesModel(int[] indexes) {
53 setIndexes(indexes, false);
54 }
55
56 public int[] listSortedIndexes() {
57 if (count == 0) {
58 return EMPTY_SELECTION;
59 }
60
61 garbage();
62
63 int a[] = new int[count];
64 System.arraycopy(selectionIndexes, 0, a, 0, count);
65
66 Arrays.sort(a);
67
68 return a;
69 }
70
71 public int getFirstIndex() {
72 if (count == 0) {
73 return -1;
74 }
75
76 garbage();
77
78 return selectionIndexes[0];
79 }
80
81 private void garbage() {
82 if (garbaged) {
83 return;
84 }
85
86 garbaged = true;
87 if (count == lastPos) {
88 return;
89 }
90
91 int lastEmpty = -1;
92 int last = -1;
93 for (int i = 0; i < lastPos; i++) {
94 int n = selectionIndexes[i];
95
96 if (n < 0) {
97 if (lastEmpty < 0) {
98 lastEmpty = i;
99 }
100
101 continue;
102 }
103
104 if (lastEmpty >= 0) {
105 selectionIndexes[lastEmpty] = n;
106 last = lastEmpty;
107 lastEmpty++;
108 continue;
109 }
110
111 last = i;
112
113 continue;
114 }
115
116
117 if (count != last + 1) {
118 LOG.error("Y a un probleme ! (count!=last)");
119 }
120
121 if (VERIFY_GARBAGE) {
122 Set set = new HashSet(count);
123 for (int i = 0; i < count; i++) {
124 if (set.add(new Integer(i)) == false) {
125 LOG.error("Y a un GROS probleme avec le garbage !");
126 }
127 }
128 }
129
130 lastPos = count;
131 }
132
133
134
135
136
137
138 public void clearIndexes() {
139 if (commited) {
140 throw new IllegalStateException("Already commited indexes model.");
141 }
142 count = 0;
143 lastPos = 0;
144 garbaged = true;
145 }
146
147
148
149
150
151
152 public boolean containsIndex(int index) {
153 if (index < 0) {
154 throw new IllegalArgumentException("Invalid index (" + index
155 + " < 0)");
156 }
157
158 if (count == 0) {
159 return false;
160 }
161
162 garbage();
163
164 for (int i = 0; i < count; i++) {
165 int n = selectionIndexes[i];
166
167 if (index == n) {
168 return true;
169 }
170 }
171
172 return false;
173 }
174
175
176
177
178
179
180 public boolean addIndex(int index) {
181 if (commited) {
182 throw new IllegalStateException("Already commited indexes model.");
183 }
184
185 if (index < 0) {
186 throw new IllegalArgumentException("Invalid index (" + index
187 + " < 0)");
188 }
189
190 for (int i = 0; i < lastPos; i++) {
191 int n = selectionIndexes[i];
192
193 if (index == n) {
194 return false;
195 }
196 }
197
198 if (lastPos < selectionIndexes.length) {
199 selectionIndexes[lastPos++] = index;
200 count++;
201 garbaged = false;
202 return true;
203 }
204
205 garbage();
206
207 if (lastPos < selectionIndexes.length) {
208 selectionIndexes[lastPos++] = index;
209 count++;
210 garbaged = false;
211 return true;
212 }
213
214
215 int d = count / 2;
216 if (d < 8) {
217 d = 8;
218 }
219 int n[] = new int[count + d];
220 if (count > 0) {
221 System.arraycopy(selectionIndexes, 0, n, 0, count);
222 }
223
224 selectionIndexes = n;
225
226 selectionIndexes[lastPos++] = index;
227 count++;
228 garbaged = false;
229
230 return true;
231 }
232
233
234
235
236
237
238 public boolean removeIndex(int index) {
239 if (commited) {
240 throw new IllegalStateException("Already commited indexes model.");
241 }
242
243 if (index < 0) {
244 throw new IllegalArgumentException("Invalid index (" + index
245 + " < 0)");
246 }
247 if (count == 0) {
248 return false;
249 }
250
251 for (int i = 0; i < lastPos; i++) {
252 if (selectionIndexes[i] != index) {
253 continue;
254 }
255
256 selectionIndexes[i] = -1;
257 count--;
258 garbaged = false;
259 return true;
260 }
261
262 return false;
263 }
264
265
266
267
268
269
270 public void setIndexes(int[] indexes) {
271 setIndexes(indexes, true);
272 }
273
274 public void setIndexes(int[] indexes, boolean copy) {
275 if (commited) {
276 throw new IllegalStateException("Already commited indexes model.");
277 }
278
279 if (indexes == null || indexes.length < 1) {
280 selectionIndexes = EMPTY_SELECTION;
281 lastPos = 0;
282 count = 0;
283 return;
284 }
285
286 if (copy) {
287 selectionIndexes = new int[indexes.length];
288 System.arraycopy(indexes, 0, selectionIndexes, 0, indexes.length);
289
290 } else {
291 selectionIndexes = indexes;
292 }
293
294 garbaged = true;
295 count = selectionIndexes.length;
296 lastPos = count;
297
298 for (int i = 0; i < selectionIndexes.length; i++) {
299 if (selectionIndexes[i] >= 0) {
300 continue;
301 }
302
303 garbaged = false;
304 count--;
305 }
306 }
307
308
309
310
311
312
313 public int countIndexes() {
314 return count;
315 }
316
317 public IIndexesModel copy() {
318 garbage();
319
320 if (LOG.isDebugEnabled()) {
321 LOG.debug("Copy model");
322 }
323
324 return new ArrayIndexesModel(selectionIndexes);
325 }
326
327 public void commit() {
328 garbage();
329
330 if (LOG.isDebugEnabled()) {
331 LOG.debug("Commit model");
332 }
333
334 commited = true;
335 }
336
337 public boolean isCommited() {
338 return commited;
339 }
340
341 }