1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| package org.jboss.cache.pojo.collection; |
8 |
| |
9 |
| import static org.jboss.cache.pojo.impl.InternalConstant.POJOCACHE_OPERATION; |
10 |
| |
11 |
| import java.io.ObjectStreamException; |
12 |
| import java.util.ArrayList; |
13 |
| import java.util.Iterator; |
14 |
| import java.util.LinkedList; |
15 |
| import java.util.List; |
16 |
| import java.util.ListIterator; |
17 |
| import java.util.NoSuchElementException; |
18 |
| import java.util.Set; |
19 |
| |
20 |
| import org.apache.commons.logging.Log; |
21 |
| import org.apache.commons.logging.LogFactory; |
22 |
| import org.jboss.cache.Cache; |
23 |
| import org.jboss.cache.Fqn; |
24 |
| import org.jboss.cache.Node; |
25 |
| import org.jboss.cache.pojo.impl.PojoCacheImpl; |
26 |
| import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor; |
27 |
| import org.jboss.cache.pojo.util.AopUtil; |
28 |
| import org.jboss.cache.pojo.util.CacheApiUtil; |
29 |
| import org.jboss.cache.pojo.util.Null; |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| public class CachedListImpl extends CachedListAbstract |
38 |
| { |
39 |
| private static Log log_ = LogFactory.getLog(CachedListImpl.class.getName()); |
40 |
| private Cache<Object, Object> cache; |
41 |
| private PojoCacheImpl pojoCache; |
42 |
| private AbstractCollectionInterceptor interceptor; |
43 |
| |
44 |
1572
| public CachedListImpl(PojoCacheImpl cache, AbstractCollectionInterceptor interceptor)
|
45 |
| { |
46 |
1572
| this.pojoCache = cache;
|
47 |
1572
| this.cache = pojoCache.getCache();
|
48 |
1572
| this.interceptor = interceptor;
|
49 |
| } |
50 |
| |
51 |
18473
| private Fqn getFqn()
|
52 |
| { |
53 |
18473
| return interceptor.getFqn();
|
54 |
| } |
55 |
| |
56 |
| |
57 |
| |
58 |
11466
| private Set<Node> getNodeChildren()
|
59 |
| { |
60 |
11466
| return CacheApiUtil.getNodeChildren(cache, getFqn());
|
61 |
| } |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
0
| private Object XwriteReplace() throws ObjectStreamException
|
67 |
| { |
68 |
0
| log_.warn("writeReplace(): this calss is not suppored to be serialized." +
|
69 |
| " Will substitue with a normal ArryList"); |
70 |
| |
71 |
0
| ArrayList toSerialize = new ArrayList();
|
72 |
0
| toSerialize.addAll(this);
|
73 |
0
| return toSerialize;
|
74 |
| } |
75 |
| |
76 |
723
| public Object get(int index)
|
77 |
| { |
78 |
723
| checkIndex();
|
79 |
723
| return Null.toNullValue(pojoCache.getObject(AopUtil.constructFqn(getFqn(), IntegerCache.toString(index))));
|
80 |
| } |
81 |
| |
82 |
5405
| private static void checkIndex()
|
83 |
| { |
84 |
| |
85 |
| |
86 |
5405
| return;
|
87 |
| |
88 |
| |
89 |
| |
90 |
| |
91 |
| |
92 |
| |
93 |
| } |
94 |
| |
95 |
11466
| public int size()
|
96 |
| { |
97 |
11466
| Set<Node> children = getNodeChildren();
|
98 |
11466
| return children == null ? 0 : children.size();
|
99 |
| } |
100 |
| |
101 |
15
| public Object set(int index, Object element)
|
102 |
| { |
103 |
15
| if (index != 0)
|
104 |
2
| checkIndex();
|
105 |
15
| return Null.toNullValue(attach(index, element, "SET"));
|
106 |
| } |
107 |
| |
108 |
3249
| public void add(int index, Object element)
|
109 |
| { |
110 |
3249
| if (index != 0)
|
111 |
1764
| checkIndex();
|
112 |
3249
| for (int i = size(); i > index; i--)
|
113 |
| { |
114 |
5
| Object obj = detach(i - 1);
|
115 |
5
| attach(i, obj);
|
116 |
| } |
117 |
3249
| attach(index, element, "ADD");
|
118 |
| } |
119 |
| |
120 |
39
| private Object attach(int i, Object obj)
|
121 |
| { |
122 |
39
| return attach(i, obj, null);
|
123 |
| } |
124 |
| |
125 |
3303
| private Object attach(int i, Object obj, String operation)
|
126 |
| { |
127 |
3303
| Fqn fqn = AopUtil.constructFqn(getFqn(), IntegerCache.toString(i));
|
128 |
3303
| Object o = pojoCache.attach(fqn, Null.toNullObject(obj));
|
129 |
3303
| if (operation != null)
|
130 |
3264
| pojoCache.getCache().put(fqn, POJOCACHE_OPERATION, operation);
|
131 |
| |
132 |
3303
| return o;
|
133 |
| } |
134 |
| |
135 |
39
| private Object detach(int i)
|
136 |
| { |
137 |
39
| return detach(i, null);
|
138 |
| } |
139 |
| |
140 |
2965
| private Object detach(int i, String operation)
|
141 |
| { |
142 |
2965
| Fqn fqn = AopUtil.constructFqn(getFqn(), IntegerCache.toString(i));
|
143 |
2965
| if (operation != null)
|
144 |
2926
| pojoCache.getCache().put(fqn, POJOCACHE_OPERATION, operation);
|
145 |
2965
| return pojoCache.detach(fqn);
|
146 |
| } |
147 |
| |
148 |
66
| public int indexOf(Object o)
|
149 |
| { |
150 |
66
| int size = size();
|
151 |
66
| if (o == null)
|
152 |
| { |
153 |
6
| for (int i = 0; i < size; i++)
|
154 |
| { |
155 |
6
| if (null == get(i))
|
156 |
3
| return i;
|
157 |
| } |
158 |
| } else |
159 |
| { |
160 |
63
| for (int i = 0; i < size; i++)
|
161 |
| { |
162 |
103
| if (o.equals(get(i)))
|
163 |
38
| return i;
|
164 |
| } |
165 |
| } |
166 |
25
| return -1;
|
167 |
| } |
168 |
| |
169 |
1
| public int lastIndexOf(Object o)
|
170 |
| { |
171 |
1
| if (o == null)
|
172 |
| { |
173 |
1
| for (int i = size() - 1; i >= 0; i--)
|
174 |
| { |
175 |
1
| if (null == get(i))
|
176 |
1
| return i;
|
177 |
| } |
178 |
| } else |
179 |
| { |
180 |
0
| for (int i = size() - 1; i >= 0; i--)
|
181 |
| { |
182 |
0
| if (o.equals(get(i)))
|
183 |
0
| return i;
|
184 |
| } |
185 |
| } |
186 |
0
| return -1;
|
187 |
| } |
188 |
| |
189 |
2916
| public Object remove(int index)
|
190 |
| { |
191 |
2916
| checkIndex();
|
192 |
| |
193 |
2916
| int size = size();
|
194 |
2916
| Object result = Null.toNullValue(detach(index, "REMOVE"));
|
195 |
2916
| if (size == (index + 1))
|
196 |
| { |
197 |
2903
| return result;
|
198 |
| } |
199 |
13
| for (int i = index; i < size - 1; i++)
|
200 |
| { |
201 |
22
| Object obj = detach(i + 1);
|
202 |
22
| attach(i, obj);
|
203 |
| } |
204 |
13
| return result;
|
205 |
| } |
206 |
| |
207 |
4
| public Iterator iterator()
|
208 |
| { |
209 |
| |
210 |
4
| return new Iterator()
|
211 |
| { |
212 |
| |
213 |
| int current = -1; |
214 |
| int size = size(); |
215 |
| |
216 |
20
| public boolean hasNext()
|
217 |
| { |
218 |
2
| if (size == 0) return false;
|
219 |
18
| if (current > size)
|
220 |
0
| throw new NoSuchElementException("CachedSetImpl.iterator.hasNext(). " +
|
221 |
| " Cursor position " + current + " is greater than the size " + size()); |
222 |
| |
223 |
18
| return current < size - 1;
|
224 |
| } |
225 |
| |
226 |
16
| public Object next()
|
227 |
| { |
228 |
16
| if (current == size)
|
229 |
0
| throw new NoSuchElementException("CachedSetImpl.iterator.next(). " +
|
230 |
| " Cursor position " + current + " is greater than the size " + size()); |
231 |
| |
232 |
16
| return Null.toNullValue(pojoCache.getObject(AopUtil.constructFqn(getFqn(), IntegerCache.toString(++current))));
|
233 |
| } |
234 |
| |
235 |
10
| public void remove()
|
236 |
| { |
237 |
| |
238 |
0
| if (size == 0) return;
|
239 |
10
| if (current == size)
|
240 |
0
| throw new IllegalStateException("CachedSetImpl.iterator.remove(). " +
|
241 |
| " Cursor position " + current + " is greater than the size " + size); |
242 |
10
| if (current < (size - 1))
|
243 |
| { |
244 |
| |
245 |
7
| Object last = detach(current, "REMOVE");
|
246 |
7
| for (int i = current + 1; i < size; i++)
|
247 |
| { |
248 |
12
| last = detach(i);
|
249 |
12
| attach(i - 1, last);
|
250 |
| } |
251 |
| } else |
252 |
| { |
253 |
| |
254 |
3
| detach(current, "REMOVE");
|
255 |
| } |
256 |
10
| current--;
|
257 |
10
| size--;
|
258 |
| } |
259 |
| }; |
260 |
| } |
261 |
| |
262 |
0
| public List subList(int fromIndex, int toIndex)
|
263 |
| { |
264 |
0
| if (fromIndex < 0)
|
265 |
0
| throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
|
266 |
0
| if (toIndex > size())
|
267 |
0
| throw new IndexOutOfBoundsException("toIndex = " + toIndex + " but size() =" + size());
|
268 |
0
| if (fromIndex > toIndex)
|
269 |
0
| throw new IllegalArgumentException("fromIndex (" + fromIndex + ") must be less than toIndex(" + toIndex + ")");
|
270 |
0
| if (fromIndex == toIndex)
|
271 |
0
| return new LinkedList();
|
272 |
0
| return new MyCachedSubListImpl(this, fromIndex, toIndex);
|
273 |
| } |
274 |
| |
275 |
5
| public ListIterator listIterator()
|
276 |
| { |
277 |
5
| return new MyListIterator(this, 0);
|
278 |
| } |
279 |
| |
280 |
0
| public ListIterator listIterator(int index)
|
281 |
| { |
282 |
0
| return new MyListIterator(this, index);
|
283 |
| } |
284 |
| |
285 |
| static class MyListIterator implements ListIterator |
286 |
| { |
287 |
| int index = 0; |
288 |
| List list_; |
289 |
| |
290 |
5
| public MyListIterator(List list, int index)
|
291 |
| { |
292 |
5
| list_ = list;
|
293 |
5
| if (index < 0 || index > list_.size())
|
294 |
| { |
295 |
0
| throw new IndexOutOfBoundsException("CachedListImpl: MyListIterator construction. " +
|
296 |
| " Index is out of bound : " + index); |
297 |
| } |
298 |
5
| this.index = index;
|
299 |
| } |
300 |
| |
301 |
5
| public int nextIndex()
|
302 |
| { |
303 |
5
| return index;
|
304 |
| } |
305 |
| |
306 |
18
| public int previousIndex()
|
307 |
| { |
308 |
18
| return index - 1;
|
309 |
| } |
310 |
| |
311 |
3
| public void remove()
|
312 |
| { |
313 |
3
| int size = list_.size();
|
314 |
0
| if (size == 0) return;
|
315 |
3
| if (previousIndex() == size)
|
316 |
0
| throw new IllegalStateException("CachedSetImpl.MyListIterator.remove(). " +
|
317 |
| " Cursor position " + index + " is greater than the size " + size); |
318 |
3
| if (previousIndex() < (size))
|
319 |
| { |
320 |
3
| list_.remove(previousIndex());
|
321 |
3
| index--;
|
322 |
| } |
323 |
| } |
324 |
| |
325 |
6
| public boolean hasNext()
|
326 |
| { |
327 |
6
| return (index < list_.size());
|
328 |
| } |
329 |
| |
330 |
1
| public boolean hasPrevious()
|
331 |
| { |
332 |
1
| return (index != 0);
|
333 |
| } |
334 |
| |
335 |
12
| public Object next()
|
336 |
| { |
337 |
12
| if (index == list_.size())
|
338 |
1
| throw new NoSuchElementException();
|
339 |
| |
340 |
11
| index++;
|
341 |
11
| return list_.get(index - 1);
|
342 |
| } |
343 |
| |
344 |
6
| public Object previous()
|
345 |
| { |
346 |
6
| if (index == 0)
|
347 |
1
| throw new NoSuchElementException();
|
348 |
| |
349 |
5
| index--;
|
350 |
5
| return list_.get(index);
|
351 |
| } |
352 |
| |
353 |
1
| public void add(Object o)
|
354 |
| { |
355 |
1
| int size = list_.size();
|
356 |
0
| if (size == 0) return;
|
357 |
| |
358 |
1
| if (previousIndex() == size)
|
359 |
0
| throw new IllegalStateException("CachedSetImpl.MyListIterator.add(). " +
|
360 |
| " Cursor position " + index + " is greater than the size " + size); |
361 |
1
| if (previousIndex() < (size))
|
362 |
| { |
363 |
1
| list_.add(previousIndex(), o);
|
364 |
| } |
365 |
| } |
366 |
| |
367 |
1
| public void set(Object o)
|
368 |
| { |
369 |
1
| int size = list_.size();
|
370 |
0
| if (size == 0) return;
|
371 |
| |
372 |
1
| if (previousIndex() == size)
|
373 |
0
| throw new IllegalStateException("CachedSetImpl.MyListIterator.set(). " +
|
374 |
| " Cursor position " + index + " is greater than the size " + size); |
375 |
1
| if (previousIndex() < (size))
|
376 |
| { |
377 |
1
| list_.set(previousIndex(), o);
|
378 |
| } |
379 |
| } |
380 |
| } |
381 |
| |
382 |
| static public class MyCachedSubListImpl extends CachedListAbstract implements List |
383 |
| { |
384 |
| |
385 |
| private List backStore_; |
386 |
| private int fromIndex_; |
387 |
| private int toIndex_; |
388 |
| |
389 |
0
| MyCachedSubListImpl(List backStore, int fromIndex, int toIndex)
|
390 |
| { |
391 |
0
| backStore_ = backStore;
|
392 |
0
| fromIndex_ = fromIndex;
|
393 |
0
| toIndex_ = toIndex;
|
394 |
| } |
395 |
| |
396 |
0
| public int size()
|
397 |
| { |
398 |
0
| int size = backStore_.size();
|
399 |
0
| if (size > toIndex_)
|
400 |
0
| size = toIndex_;
|
401 |
0
| size -= fromIndex_;
|
402 |
0
| return size;
|
403 |
| } |
404 |
| |
405 |
0
| public Iterator iterator()
|
406 |
| { |
407 |
| |
408 |
0
| return new Iterator()
|
409 |
| { |
410 |
| int current = -1; |
411 |
| Iterator iter_ = initializeIter(); |
412 |
| |
413 |
0
| private Iterator initializeIter()
|
414 |
| { |
415 |
0
| Iterator iter = backStore_.iterator();
|
416 |
0
| for (int looper = 0; looper < fromIndex_; looper++)
|
417 |
0
| if (iter.hasNext())
|
418 |
0
| iter.next();
|
419 |
0
| return iter;
|
420 |
| } |
421 |
| |
422 |
0
| public boolean hasNext()
|
423 |
| { |
424 |
0
| int size = size();
|
425 |
0
| if (size == 0) return false;
|
426 |
0
| if (current > size)
|
427 |
0
| throw new IllegalStateException("CachedSetImpl.MyCachedSubListImpl.iterator.hasNext(). " +
|
428 |
| " Cursor position " + current + " is greater than the size " + size()); |
429 |
| |
430 |
0
| return current < size() - 1;
|
431 |
| } |
432 |
| |
433 |
0
| public Object next()
|
434 |
| { |
435 |
0
| if (current == size())
|
436 |
0
| throw new IllegalStateException("CachedSetImpl.MyCachedSubListImpl.iterator.next(). " +
|
437 |
| " Cursor position " + current + " is greater than the size " + size()); |
438 |
0
| current++;
|
439 |
0
| return iter_.next();
|
440 |
| } |
441 |
| |
442 |
0
| public void remove()
|
443 |
| { |
444 |
0
| iter_.remove();
|
445 |
0
| current--;
|
446 |
| } |
447 |
| }; |
448 |
| |
449 |
| } |
450 |
| |
451 |
0
| public Object get(int index)
|
452 |
| { |
453 |
0
| checkIndex(index);
|
454 |
0
| return backStore_.get(index + fromIndex_);
|
455 |
| } |
456 |
| |
457 |
0
| public Object set(int index, Object element)
|
458 |
| { |
459 |
0
| checkIndex(index);
|
460 |
0
| return backStore_.set(index + fromIndex_, element);
|
461 |
| } |
462 |
| |
463 |
0
| public void add(int index, Object element)
|
464 |
| { |
465 |
0
| backStore_.add(index + fromIndex_, element);
|
466 |
| } |
467 |
| |
468 |
0
| public Object remove(int index)
|
469 |
| { |
470 |
0
| return backStore_.remove(index + fromIndex_);
|
471 |
| } |
472 |
| |
473 |
0
| public int indexOf(Object o)
|
474 |
| { |
475 |
0
| int index = backStore_.indexOf(o);
|
476 |
0
| if (index < fromIndex_ || index >= toIndex_)
|
477 |
0
| index = -1;
|
478 |
| else |
479 |
0
| index -= fromIndex_;
|
480 |
0
| return index;
|
481 |
| } |
482 |
| |
483 |
0
| public int lastIndexOf(Object o)
|
484 |
| { |
485 |
0
| int index = backStore_.lastIndexOf(o);
|
486 |
0
| if (index < fromIndex_ || index >= toIndex_)
|
487 |
0
| index = -1;
|
488 |
| else |
489 |
0
| index -= fromIndex_;
|
490 |
0
| return index;
|
491 |
| } |
492 |
| |
493 |
0
| public ListIterator listIterator()
|
494 |
| { |
495 |
0
| return new MyListIterator(this, 0);
|
496 |
| } |
497 |
| |
498 |
0
| public ListIterator listIterator(int index)
|
499 |
| { |
500 |
0
| return new MyListIterator(this, index);
|
501 |
| } |
502 |
| |
503 |
0
| public List subList(int fromIndex, int toIndex)
|
504 |
| { |
505 |
0
| if (fromIndex < 0)
|
506 |
0
| throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
|
507 |
0
| if (toIndex > size())
|
508 |
0
| throw new IndexOutOfBoundsException("toIndex = " + toIndex + " but size() =" + size());
|
509 |
0
| if (fromIndex > toIndex)
|
510 |
0
| throw new IllegalArgumentException("fromIndex (" + fromIndex + ") must be less than toIndex(" + toIndex + ")");
|
511 |
0
| if (fromIndex == toIndex)
|
512 |
0
| return new LinkedList();
|
513 |
0
| return new MyCachedSubListImpl(this, fromIndex, toIndex);
|
514 |
| } |
515 |
| |
516 |
0
| private void checkIndex(int i)
|
517 |
| { |
518 |
0
| if (size() == 0) return;
|
519 |
0
| if (i < 0 || i >= size())
|
520 |
| { |
521 |
0
| throw new IndexOutOfBoundsException("Index out of bound at CachedListImpl(). Index is " + i
|
522 |
| + " but size is " + size()); |
523 |
| } |
524 |
| } |
525 |
| |
526 |
| } |
527 |
| |
528 |
| } |