1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.caleigo.core;
20
21
22 import java.util.*;
23
24 import org.caleigo.core.event.*;
25
26 /*** <Description for OrderedProxySelection>
27 *
28 * @author Dennis Zikovic
29 * @version 1.00
30 *
31 *//*
32 *
33 * WHEN WHO WHY & WHAT
34 * -----------------------------------------------------------------------------
35 * 2001-12-07 Dennis Zikovic Creation
36 */
37 public class OrderedProxySelection extends ProxySelection
38 {
39
40
41
42 private int[] mIndexArray;
43 private Comparator mComparator;
44
45
46
47 /*** Creates new OrderedProxySelection
48 */
49 public OrderedProxySelection(IEntityDescriptor entityDescriptor)
50 {
51 super(entityDescriptor);
52 }
53
54 /*** Creates new OrderedProxySelection
55 */
56 public OrderedProxySelection(IEntityDescriptor entityDescriptor, Comparator comparator)
57 {
58 this(entityDescriptor);
59 mComparator = comparator;
60 }
61
62 /*** Creates new OrderedProxySelection
63 */
64 public OrderedProxySelection(ISelection selection)
65 {
66 super(selection);
67 }
68
69 /*** Creates new OrderedProxySelection
70 */
71 public OrderedProxySelection(ISelection selection, Comparator comparator)
72 {
73 this(selection);
74 mComparator = comparator;
75 this.sort();
76 }
77
78
79
80 /*** Adds the provided IEntity object to at the specified index in the
81 * selection object. If an entity with the same identity already exists
82 * in the selection the requeat is ignored and false is returned.
83 */
84 public boolean addEntity(int index, IEntity entity)
85 {
86 if(this.getRemoteSelection()!=null)
87 return this.getRemoteSelection().addEntity(this.getRemoteIndex(index), entity);
88 else
89 return false;
90 }
91
92 /*** Access method that returns the contained IEntity object with the
93 * specified index.
94 */
95 public IEntity getEntity(int index)
96 {
97 if(this.getRemoteSelection()!=null)
98 return this.getRemoteSelection().getEntity(this.getRemoteIndex(index));
99 else
100 return null;
101 }
102
103 /*** Mutation method that removes the indexed entity from the selection.
104 * Returns the indexed entity if it was found and removed otherwise null
105 * is returned. The entities are not effecte in any other way.
106 */
107 public IEntity removeEntity(int index)
108 {
109 if(this.getRemoteSelection()!=null)
110 return this.getRemoteSelection().removeEntity(this.getRemoteIndex(index));
111 else
112 return null;
113 }
114
115 /*** Access method that views the selection objct as a grid where row is
116 * the entity index and column is the field index for the stored entities.
117 */
118 public Object getData(int row, int column)
119 {
120 if(this.getRemoteSelection()!=null)
121 return this.getRemoteSelection().getData(this.getRemoteIndex(row), column);
122 else
123 return this.getEntityDescriptor().getFieldDescriptor(column).getDefaultValue();
124 }
125
126 /*** Mutation method that views the selection objct as a grid where row is
127 * the entity index and column is the field index for the stored entities.
128 */
129 public void setData(int row, int column, Object dataValue)
130 {
131 if(this.getRemoteSelection()!=null)
132 this.getRemoteSelection().setData(this.getRemoteIndex(row), column, dataValue);
133 }
134
135 /*** Creates a sub selection with the indexed entities in the called
136 * selection. The created selection that should be independant of changes
137 * in the source/called selection after the time of creation.
138 */
139 public ISelection createSubSelection(int[] indexArray)
140 {
141 ISelection selection = new Selection(this.getEntityDescriptor());
142 for(int j=0; j<indexArray.length; j++)
143 selection.addEntity(this.getEntity(indexArray[j]));
144 return selection;
145 }
146
147 /*** Help method that returns the index of the provided IEntity object in
148 * the selection if it exists othewise a negative value is returned.
149 */
150 public int indexOf(IEntity entity)
151 {
152 if(this.getRemoteSelection()!=null)
153 return this.getOrderedIndex(this.getRemoteSelection().indexOf(entity));
154 else
155 return -1;
156 }
157
158 /*** Access method that returns the selections relay listener.
159 */
160 protected RelayListener createRelayListener()
161 {
162 return new OrderedRelayListener();
163 }
164
165 /*** Overriden to sort the index map for the new remote selection.
166 */
167 protected void doAfterRemoteChange()
168 {
169 this.sort();
170 }
171
172
173
174 public Comparator getComparator()
175 {
176 return mComparator;
177 }
178
179 public void setComparator(Comparator comp)
180 {
181 mComparator = comp;
182 this.sort();
183 }
184
185 public void setCollationField(IFieldDescriptor fieldDescriptor)
186 {
187 this.setCollationField(fieldDescriptor, true);
188 }
189
190 public void setCollationField(IFieldDescriptor fieldDescriptor, boolean ascending)
191 {
192 mComparator = new EntityCollator(this.getEntityDescriptor());
193 ((EntityCollator)mComparator).addCollationField(fieldDescriptor, ascending);
194 this.sort();
195 }
196
197 public void addCollationField(IFieldDescriptor fieldDescriptor)
198 {
199 this.addCollationField(fieldDescriptor, true);
200 }
201
202 public void addCollationField(IFieldDescriptor fieldDescriptor, boolean ascending)
203 {
204 if(!(mComparator instanceof EntityCollator))
205 mComparator = new EntityCollator(this.getEntityDescriptor());
206 ((EntityCollator)mComparator).addCollationField(fieldDescriptor, ascending);
207 this.sort();
208 }
209
210 public void clearCollationFields()
211 {
212 mComparator = null;
213 }
214
215 /*** Converts an ordered entity index to a remote unordered index.
216 */
217 public int getRemoteIndex(int orderedIndex)
218 {
219 if(mComparator!=null && mIndexArray!=null && mIndexArray.length>0)
220 return mIndexArray[orderedIndex];
221 else
222 return orderedIndex;
223 }
224
225 /*** Converts a remote unordered entity index to an ordered index.
226 */
227 public int getOrderedIndex(int remoteIndex)
228 {
229 if(mComparator==null || mIndexArray==null)
230 return remoteIndex;
231
232 int orderedIndex = mIndexArray.length-1;
233 while(orderedIndex>=0 && mIndexArray[orderedIndex]!=remoteIndex)
234 orderedIndex--;
235 return orderedIndex;
236 }
237
238
239
240 /*** Sorts the selection using the current entity collator. Note that the
241 * sort is automatically called when a new collator is set using any of
242 * the order changing methods in the object. The method should however be
243 * used if the registered Comperator is changed externally.
244 */
245 public void sort()
246 {
247 if(!this.hasRemoteSelection())
248 mIndexArray = null;
249
250
251 if(mComparator==null || !this.hasRemoteSelection())
252 return;
253
254
255 ISelection remoteSelection = this.getRemoteSelection();
256 if(mIndexArray==null || mIndexArray.length!=remoteSelection.size())
257 {
258 if(mIndexArray!=null && mIndexArray.length<remoteSelection.size())
259 {
260
261 int[] oldArray = mIndexArray;
262 mIndexArray = new int[remoteSelection.size()];
263 System.arraycopy(oldArray, 0, mIndexArray, 0, oldArray.length);
264 for(int j=oldArray.length; j<mIndexArray.length; j++)
265 mIndexArray[j] = j;
266 }
267 else
268 {
269
270 mIndexArray = new int[remoteSelection.size()];
271 for(int j=0; j<mIndexArray.length; j++)
272 mIndexArray[j] = j;
273 }
274 }
275
276
277 boolean orderChanged = false;
278 int j, k, tmp;
279 for(j=1; j<mIndexArray.length; j++)
280 {
281 k=j;
282 while(k>0 && mComparator.compare(remoteSelection.getEntity(mIndexArray[j]), remoteSelection.getEntity(mIndexArray[k-1])) < 0)
283 k--;
284
285 if(k<j)
286 {
287 tmp = mIndexArray[j];
288 System.arraycopy(mIndexArray, k, mIndexArray, k+1, j-k);
289 mIndexArray[k] = tmp;
290 orderChanged = true;
291 }
292 }
293
294
295 if(orderChanged)
296 this.fireContentsChanged();
297 }
298
299
300
301 protected class OrderedRelayListener extends RelayListener
302 {
303
304 public void entityRemoved(SelectionEvent event)
305 {
306
307 sort();
308 super.entityRemoved(event);
309 }
310
311 public void entityAdded(SelectionEvent event)
312 {
313
314 if(mComparator!=null && hasRemoteSelection())
315 {
316 ISelection remoteSelection = getRemoteSelection();
317 int[] newIndexArray = new int[mIndexArray.length + 1];
318 int insertIndex = -1;
319
320
321 for (int j=0; j<mIndexArray.length; j++)
322 if (mComparator.compare(remoteSelection.getEntity(mIndexArray[j]), event.getEntity()) > 0)
323 {
324 insertIndex = j;
325 break;
326 }
327
328
329 if (insertIndex == -1)
330 insertIndex = newIndexArray.length - 1;
331
332
333 newIndexArray[insertIndex] = remoteSelection.indexOf(event.getEntity());
334 System.arraycopy(mIndexArray, 0, newIndexArray, 0, insertIndex);
335 System.arraycopy(mIndexArray, insertIndex, newIndexArray, insertIndex + 1, mIndexArray.length - insertIndex);
336
337 mIndexArray = newIndexArray;
338 }
339
340 super.entityAdded(event);
341 }
342
343 public void contentsChanged(SelectionEvent event)
344 {
345 sort();
346 super.contentsChanged(event);
347 }
348
349
350 public void dataChanged(EntityChangeEvent event)
351 {
352
353
354 sort();
355 super.dataChanged(event);
356 }
357
358
359 public void remoteChanged(ProxyEvent event)
360 {
361 sort();
362 super.remoteChanged(event);
363 }
364 }
365 }