PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Java.NET/JavApi Commons collections (Apache Port)/org.apache.commons.collections.CursorableLinkedList.cs

https://github.com/gadfly/nofs
C# | 1428 lines | 873 code | 96 blank | 459 comment | 211 complexity | 3501edcb102fbcc6063421982fa3ca8a MD5 | raw file
  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. *
  14. */
  15. using System;
  16. using java = biz.ritter.javapi;
  17. namespace org.apache.commons.collections
  18. {
  19. /**
  20. * A doubly-linked list implementation of the {@link List} interface,
  21. * supporting a {@link ListIterator} that allows concurrent modifications
  22. * to the underlying list.
  23. * <p>
  24. * Implements all of the optional {@link List} operations, the
  25. * stack/queue/dequeue operations available in {@link java.util.LinkedList}
  26. * and supports a {@link ListIterator} that allows concurrent modifications
  27. * to the underlying list (see {@link #cursor}).
  28. * <p>
  29. * <b>Note that this implementation is not synchronized.</b>
  30. *
  31. * @deprecated Use new version in list subpackage, which has been rewritten
  32. * and now returns the cursor from the listIterator method. Will be removed in v4.0
  33. * @see java.util.LinkedList
  34. * @since Commons Collections 1.0
  35. * @version $Revision$ $Date$
  36. *
  37. * @author Rodney Waldhoff
  38. * @author Janek Bogucki
  39. * @author Simon Kitching
  40. */
  41. [Serializable]
  42. public class CursorableLinkedList : java.util.List<Object>, java.io.Serializable
  43. {
  44. /** Ensure serialization compatibility */
  45. private static readonly long serialVersionUID = 8836393098519411393L;
  46. //--- public methods ---------------------------------------------
  47. /**
  48. * Appends the specified element to the end of this list.
  49. *
  50. * @param o element to be appended to this list.
  51. * @return <tt>true</tt>
  52. */
  53. public virtual bool add(Object o)
  54. {
  55. insertListable(_head.prev(), null, o);
  56. return true;
  57. }
  58. /**
  59. * Inserts the specified element at the specified position in this list.
  60. * Shifts the element currently at that position (if any) and any subsequent
  61. * elements to the right (adds one to their indices).
  62. *
  63. * @param index index at which the specified element is to be inserted.
  64. * @param element element to be inserted.
  65. *
  66. * @throws ClassCastException if the class of the specified element
  67. * prevents it from being added to this list.
  68. * @throws IllegalArgumentException if some aspect of the specified
  69. * element prevents it from being added to this list.
  70. * @throws IndexOutOfBoundsException if the index is out of range
  71. * (index &lt; 0 || index &gt; size()).
  72. */
  73. public virtual void add(int index, Object element)
  74. {
  75. if (index == _size)
  76. {
  77. add(element);
  78. }
  79. else
  80. {
  81. if (index < 0 || index > _size)
  82. {
  83. throw new java.lang.IndexOutOfBoundsException("" + index + " < 0 or " + index + " > " + _size);
  84. }
  85. Listable succ = (isEmpty() ? null : getListableAt(index));
  86. Listable pred = (null == succ ? null : succ.prev());
  87. insertListable(pred, succ, element);
  88. }
  89. }
  90. /**
  91. * Appends all of the elements in the specified collection to the end of
  92. * this list, in the order that they are returned by the specified
  93. * {@link Collection}'s {@link Iterator}. The behavior of this operation is
  94. * unspecified if the specified collection is modified while
  95. * the operation is in progress. (Note that this will occur if the
  96. * specified collection is this list, and it's nonempty.)
  97. *
  98. * @param c collection whose elements are to be added to this list.
  99. * @return <tt>true</tt> if this list changed as a result of the call.
  100. *
  101. * @throws ClassCastException if the class of an element in the specified
  102. * collection prevents it from being added to this list.
  103. * @throws IllegalArgumentException if some aspect of an element in the
  104. * specified collection prevents it from being added to this
  105. * list.
  106. */
  107. public virtual bool addAll(java.util.Collection<Object> c)
  108. {
  109. if (c.isEmpty())
  110. {
  111. return false;
  112. }
  113. java.util.Iterator<Object> it = c.iterator();
  114. while (it.hasNext())
  115. {
  116. insertListable(_head.prev(), null, it.next());
  117. }
  118. return true;
  119. }
  120. /**
  121. * Inserts all of the elements in the specified collection into this
  122. * list at the specified position. Shifts the element currently at
  123. * that position (if any) and any subsequent elements to the right
  124. * (increases their indices). The new elements will appear in this
  125. * list in the order that they are returned by the specified
  126. * {@link Collection}'s {@link Iterator}. The behavior of this operation is
  127. * unspecified if the specified collection is modified while the
  128. * operation is in progress. (Note that this will occur if the specified
  129. * collection is this list, and it's nonempty.)
  130. *
  131. * @param index index at which to insert first element from the specified
  132. * collection.
  133. * @param c elements to be inserted into this list.
  134. * @return <tt>true</tt> if this list changed as a result of the call.
  135. *
  136. * @throws ClassCastException if the class of one of elements of the
  137. * specified collection prevents it from being added to this
  138. * list.
  139. * @throws IllegalArgumentException if some aspect of one of elements of
  140. * the specified collection prevents it from being added to
  141. * this list.
  142. * @throws IndexOutOfBoundsException if the index is out of range (index
  143. * &lt; 0 || index &gt; size()).
  144. */
  145. public virtual bool addAll(int index, java.util.Collection<Object> c)
  146. {
  147. if (c.isEmpty())
  148. {
  149. return false;
  150. }
  151. else if (_size == index || _size == 0)
  152. {
  153. return addAll(c);
  154. }
  155. else
  156. {
  157. Listable succ = getListableAt(index);
  158. Listable pred = (null == succ) ? null : succ.prev();
  159. java.util.Iterator<Object> it = c.iterator();
  160. while (it.hasNext())
  161. {
  162. pred = insertListable(pred, succ, it.next());
  163. }
  164. return true;
  165. }
  166. }
  167. /**
  168. * Inserts the specified element at the beginning of this list.
  169. * (Equivalent to {@link #add(int,java.lang.Object) <tt>add(0,o)</tt>}).
  170. *
  171. * @param o element to be prepended to this list.
  172. * @return <tt>true</tt>
  173. */
  174. public virtual bool addFirst(Object o)
  175. {
  176. insertListable(null, _head.next(), o);
  177. return true;
  178. }
  179. /**
  180. * Inserts the specified element at the end of this list.
  181. * (Equivalent to {@link #add(java.lang.Object)}).
  182. *
  183. * @param o element to be appended to this list.
  184. * @return <tt>true</tt>
  185. */
  186. public virtual bool addLast(Object o)
  187. {
  188. insertListable(_head.prev(), null, o);
  189. return true;
  190. }
  191. /**
  192. * Removes all of the elements from this list. This
  193. * list will be empty after this call returns (unless
  194. * it throws an exception).
  195. */
  196. public virtual void clear()
  197. {
  198. /*
  199. // this is the quick way, but would force us
  200. // to break all the cursors
  201. _modCount++;
  202. _head.setNext(null);
  203. _head.setPrev(null);
  204. _size = 0;
  205. */
  206. java.util.Iterator<Object> it = iterator();
  207. while (it.hasNext())
  208. {
  209. it.next();
  210. it.remove();
  211. }
  212. }
  213. /**
  214. * Returns <tt>true</tt> if this list contains the specified element.
  215. * More formally, returns <tt>true</tt> if and only if this list contains
  216. * at least one element <tt>e</tt> such that
  217. * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  218. *
  219. * @param o element whose presence in this list is to be tested.
  220. * @return <tt>true</tt> if this list contains the specified element.
  221. */
  222. public virtual bool contains(Object o)
  223. {
  224. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  225. {
  226. if ((null == o && null == elt.value()) ||
  227. (o != null && o.equals(elt.value())))
  228. {
  229. return true;
  230. }
  231. }
  232. return false;
  233. }
  234. /**
  235. * Returns <tt>true</tt> if this list contains all of the elements of the
  236. * specified collection.
  237. *
  238. * @param c collection to be checked for containment in this list.
  239. * @return <tt>true</tt> if this list contains all of the elements of the
  240. * specified collection.
  241. */
  242. public virtual bool containsAll(java.util.Collection<Object> c)
  243. {
  244. java.util.Iterator<Object> it = c.iterator();
  245. while (it.hasNext())
  246. {
  247. if (!this.contains(it.next()))
  248. {
  249. return false;
  250. }
  251. }
  252. return true;
  253. }
  254. /**
  255. * Returns a {@link ListIterator} for iterating through the
  256. * elements of this list. Unlike {@link #iterator}, a cursor
  257. * is not bothered by concurrent modifications to the
  258. * underlying list.
  259. * <p>
  260. * Specifically, when elements are added to the list before or
  261. * after the cursor, the cursor simply picks them up automatically.
  262. * When the "current" (i.e., last returned by {@link ListIterator#next}
  263. * or {@link ListIterator#previous}) element of the list is removed,
  264. * the cursor automatically adjusts to the change (invalidating the
  265. * last returned value--i.e., it cannot be removed).
  266. * <p>
  267. * Note that the returned {@link ListIterator} does not support the
  268. * {@link ListIterator#nextIndex} and {@link ListIterator#previousIndex}
  269. * methods (they throw {@link UnsupportedOperationException} when invoked.
  270. * <p>
  271. * Historical Note: In previous versions of this class, the object
  272. * returned from this method was required to be explicitly closed. This
  273. * is no longer necessary.
  274. *
  275. * @see #cursor(int)
  276. * @see #listIterator
  277. * @see CursorableLinkedList.Cursor
  278. */
  279. public virtual CursorableLinkedList.Cursor cursor()
  280. {
  281. return new Cursor(0, this);
  282. }
  283. /**
  284. * Returns a {@link ListIterator} for iterating through the
  285. * elements of this list, initialized such that
  286. * {@link ListIterator#next} will return the element at
  287. * the specified index (if any) and {@link ListIterator#previous}
  288. * will return the element immediately preceding it (if any).
  289. * Unlike {@link #iterator}, a cursor
  290. * is not bothered by concurrent modifications to the
  291. * underlying list.
  292. *
  293. * @see #cursor
  294. * @see #listIterator(int)
  295. * @see CursorableLinkedList.Cursor
  296. * @throws IndexOutOfBoundsException if the index is out of range (index
  297. * &lt; 0 || index &gt; size()).
  298. */
  299. public virtual CursorableLinkedList.Cursor cursor(int i)
  300. {
  301. return new Cursor(i, this);
  302. }
  303. /**
  304. * Compares the specified object with this list for equality. Returns
  305. * <tt>true</tt> if and only if the specified object is also a list, both
  306. * lists have the same size, and all corresponding pairs of elements in
  307. * the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
  308. * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
  309. * e1.equals(e2))</tt>.) In other words, two lists are defined to be
  310. * equal if they contain the same elements in the same order. This
  311. * definition ensures that the equals method works properly across
  312. * different implementations of the <tt>List</tt> interface.
  313. *
  314. * @param o the object to be compared for equality with this list.
  315. * @return <tt>true</tt> if the specified object is equal to this list.
  316. */
  317. public override bool Equals(Object o)
  318. {
  319. if (o == this)
  320. {
  321. return true;
  322. }
  323. else if (!(o is java.util.List<Object>))
  324. {
  325. return false;
  326. }
  327. java.util.Iterator<Object> it = ((java.util.List<Object>)o).listIterator();
  328. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  329. {
  330. if (!it.hasNext() || (null == elt.value() ? null != it.next() : !(elt.value().equals(it.next()))))
  331. {
  332. return false;
  333. }
  334. }
  335. return !it.hasNext();
  336. }
  337. /**
  338. * Returns the element at the specified position in this list.
  339. *
  340. * @param index index of element to return.
  341. * @return the element at the specified position in this list.
  342. *
  343. * @throws IndexOutOfBoundsException if the index is out of range (index
  344. * &lt; 0 || index &gt;= size()).
  345. */
  346. public virtual Object get(int index)
  347. {
  348. return getListableAt(index).value();
  349. }
  350. /**
  351. * Returns the element at the beginning of this list.
  352. */
  353. public virtual Object getFirst()
  354. {
  355. try
  356. {
  357. return _head.next().value();
  358. }
  359. catch (java.lang.NullPointerException e)
  360. {
  361. throw new java.util.NoSuchElementException(e.Message); // Basties note: giving more informations
  362. }
  363. }
  364. /**
  365. * Returns the element at the end of this list.
  366. */
  367. public virtual Object getLast()
  368. {
  369. try
  370. {
  371. return _head.prev().value();
  372. }
  373. catch (java.lang.NullPointerException e)
  374. {
  375. throw new java.util.NoSuchElementException(e.Message); // Basties note: giving more informations
  376. }
  377. }
  378. /**
  379. * Returns the hash code value for this list. The hash code of a list
  380. * is defined to be the result of the following calculation:
  381. * <pre>
  382. * hashCode = 1;
  383. * Iterator i = list.iterator();
  384. * while (i.hasNext()) {
  385. * Object obj = i.next();
  386. * hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
  387. * }
  388. * </pre>
  389. * This ensures that <tt>list1.equals(list2)</tt> implies that
  390. * <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
  391. * <tt>list1</tt> and <tt>list2</tt>, as required by the general
  392. * contract of <tt>Object.hashCode</tt>.
  393. *
  394. * @return the hash code value for this list.
  395. * @see Object#hashCode()
  396. * @see Object#equals(Object)
  397. * @see #equals(Object)
  398. */
  399. public override int GetHashCode()
  400. {
  401. int hash = 1;
  402. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  403. {
  404. hash = 31 * hash + (null == elt.value() ? 0 : elt.value().GetHashCode());
  405. }
  406. return hash;
  407. }
  408. /**
  409. * Returns the index in this list of the first occurrence of the specified
  410. * element, or -1 if this list does not contain this element.
  411. * More formally, returns the lowest index <tt>i</tt> such that
  412. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
  413. * or -1 if there is no such index.
  414. *
  415. * @param o element to search for.
  416. * @return the index in this list of the first occurrence of the specified
  417. * element, or -1 if this list does not contain this element.
  418. */
  419. public virtual int indexOf(Object o)
  420. {
  421. int ndx = 0;
  422. // perform the null check outside of the loop to save checking every
  423. // single time through the loop.
  424. if (null == o)
  425. {
  426. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  427. {
  428. if (null == elt.value())
  429. {
  430. return ndx;
  431. }
  432. ndx++;
  433. }
  434. }
  435. else
  436. {
  437. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  438. {
  439. if (o.equals(elt.value()))
  440. {
  441. return ndx;
  442. }
  443. ndx++;
  444. }
  445. }
  446. return -1;
  447. }
  448. /**
  449. * Returns <tt>true</tt> if this list contains no elements.
  450. * @return <tt>true</tt> if this list contains no elements.
  451. */
  452. public virtual bool isEmpty()
  453. {
  454. return (0 == _size);
  455. }
  456. /**
  457. * Returns a fail-fast iterator.
  458. * @see List#iterator
  459. */
  460. public virtual java.util.Iterator<Object> iterator()
  461. {
  462. return listIterator(0);
  463. }
  464. /**
  465. * Returns the index in this list of the last occurrence of the specified
  466. * element, or -1 if this list does not contain this element.
  467. * More formally, returns the highest index <tt>i</tt> such that
  468. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
  469. * or -1 if there is no such index.
  470. *
  471. * @param o element to search for.
  472. * @return the index in this list of the last occurrence of the specified
  473. * element, or -1 if this list does not contain this element.
  474. */
  475. public virtual int lastIndexOf(Object o)
  476. {
  477. int ndx = _size - 1;
  478. // perform the null check outside of the loop to save checking every
  479. // single time through the loop.
  480. if (null == o)
  481. {
  482. for (Listable elt = _head.prev(), past = null; null != elt && past != _head.next(); elt = (past = elt).prev())
  483. {
  484. if (null == elt.value())
  485. {
  486. return ndx;
  487. }
  488. ndx--;
  489. }
  490. }
  491. else
  492. {
  493. for (Listable elt = _head.prev(), past = null; null != elt && past != _head.next(); elt = (past = elt).prev())
  494. {
  495. if (o.equals(elt.value()))
  496. {
  497. return ndx;
  498. }
  499. ndx--;
  500. }
  501. }
  502. return -1;
  503. }
  504. /**
  505. * Returns a fail-fast ListIterator.
  506. * @see List#listIterator
  507. */
  508. public virtual java.util.ListIterator<Object> listIterator()
  509. {
  510. return listIterator(0);
  511. }
  512. /**
  513. * Returns a fail-fast ListIterator.
  514. * @see List#listIterator(int)
  515. */
  516. public virtual java.util.ListIterator<Object> listIterator(int index)
  517. {
  518. if (index < 0 || index > _size)
  519. {
  520. throw new java.lang.IndexOutOfBoundsException(index + " < 0 or > " + _size);
  521. }
  522. return new ListIter(index, this);
  523. }
  524. /**
  525. * Removes the first occurrence in this list of the specified element.
  526. * If this list does not contain the element, it is
  527. * unchanged. More formally, removes the element with the lowest index i
  528. * such that <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> (if
  529. * such an element exists).
  530. *
  531. * @param o element to be removed from this list, if present.
  532. * @return <tt>true</tt> if this list contained the specified element.
  533. */
  534. public virtual bool remove(Object o)
  535. {
  536. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  537. {
  538. if (null == o && null == elt.value())
  539. {
  540. removeListable(elt);
  541. return true;
  542. }
  543. else if (o != null && o.equals(elt.value()))
  544. {
  545. removeListable(elt);
  546. return true;
  547. }
  548. }
  549. return false;
  550. }
  551. /**
  552. * Removes the element at the specified position in this list (optional
  553. * operation). Shifts any subsequent elements to the left (subtracts one
  554. * from their indices). Returns the element that was removed from the
  555. * list.
  556. *
  557. * @param index the index of the element to removed.
  558. * @return the element previously at the specified position.
  559. *
  560. * @throws IndexOutOfBoundsException if the index is out of range (index
  561. * &lt; 0 || index &gt;= size()).
  562. */
  563. public virtual Object remove(int index)
  564. {
  565. Listable elt = getListableAt(index);
  566. Object ret = elt.value();
  567. removeListable(elt);
  568. return ret;
  569. }
  570. /**
  571. * Removes from this list all the elements that are contained in the
  572. * specified collection.
  573. *
  574. * @param c collection that defines which elements will be removed from
  575. * this list.
  576. * @return <tt>true</tt> if this list changed as a result of the call.
  577. */
  578. public virtual bool removeAll(java.util.Collection<Object> c)
  579. {
  580. if (0 == c.size() || 0 == _size)
  581. {
  582. return false;
  583. }
  584. else
  585. {
  586. bool changed = false;
  587. java.util.Iterator<Object> it = iterator();
  588. while (it.hasNext())
  589. {
  590. if (c.contains(it.next()))
  591. {
  592. it.remove();
  593. changed = true;
  594. }
  595. }
  596. return changed;
  597. }
  598. }
  599. /**
  600. * Removes the first element of this list, if any.
  601. */
  602. public virtual Object removeFirst()
  603. {
  604. if (_head.next() != null)
  605. {
  606. Object val = _head.next().value();
  607. removeListable(_head.next());
  608. return val;
  609. }
  610. else
  611. {
  612. throw new java.util.NoSuchElementException();
  613. }
  614. }
  615. /**
  616. * Removes the last element of this list, if any.
  617. */
  618. public virtual Object removeLast()
  619. {
  620. if (_head.prev() != null)
  621. {
  622. Object val = _head.prev().value();
  623. removeListable(_head.prev());
  624. return val;
  625. }
  626. else
  627. {
  628. throw new java.util.NoSuchElementException();
  629. }
  630. }
  631. /**
  632. * Retains only the elements in this list that are contained in the
  633. * specified collection. In other words, removes
  634. * from this list all the elements that are not contained in the specified
  635. * collection.
  636. *
  637. * @param c collection that defines which elements this set will retain.
  638. *
  639. * @return <tt>true</tt> if this list changed as a result of the call.
  640. */
  641. public virtual bool retainAll(java.util.Collection<Object> c)
  642. {
  643. bool changed = false;
  644. java.util.Iterator<Object> it = iterator();
  645. while (it.hasNext())
  646. {
  647. if (!c.contains(it.next()))
  648. {
  649. it.remove();
  650. changed = true;
  651. }
  652. }
  653. return changed;
  654. }
  655. /**
  656. * Replaces the element at the specified position in this list with the
  657. * specified element.
  658. *
  659. * @param index index of element to replace.
  660. * @param element element to be stored at the specified position.
  661. * @return the element previously at the specified position.
  662. *
  663. * @throws ClassCastException if the class of the specified element
  664. * prevents it from being added to this list.
  665. * @throws IllegalArgumentException if some aspect of the specified
  666. * element prevents it from being added to this list.
  667. * @throws IndexOutOfBoundsException if the index is out of range
  668. * (index &lt; 0 || index &gt;= size()).
  669. */
  670. public virtual Object set(int index, Object element)
  671. {
  672. Listable elt = getListableAt(index);
  673. Object val = elt.setValue(element);
  674. broadcastListableChanged(elt);
  675. return val;
  676. }
  677. /**
  678. * Returns the number of elements in this list.
  679. * @return the number of elements in this list.
  680. */
  681. public virtual int size()
  682. {
  683. return _size;
  684. }
  685. /**
  686. * Returns an array containing all of the elements in this list in proper
  687. * sequence. Obeys the general contract of the {@link Collection#toArray} method.
  688. *
  689. * @return an array containing all of the elements in this list in proper
  690. * sequence.
  691. */
  692. public virtual Object[] toArray()
  693. {
  694. Object[] array = new Object[_size];
  695. int i = 0;
  696. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  697. {
  698. array[i++] = elt.value();
  699. }
  700. return array;
  701. }
  702. /**
  703. * Returns an array containing all of the elements in this list in proper
  704. * sequence; the runtime type of the returned array is that of the
  705. * specified array. Obeys the general contract of the
  706. * {@link Collection#toArray} method.
  707. *
  708. * @param a the array into which the elements of this list are to
  709. * be stored, if it is big enough; otherwise, a new array of the
  710. * same runtime type is allocated for this purpose.
  711. * @return an array containing the elements of this list.
  712. * @exception ArrayStoreException
  713. * if the runtime type of the specified array
  714. * is not a supertype of the runtime type of every element in
  715. * this list.
  716. */
  717. public virtual Object[] toArray<Object>(Object[] a)
  718. {
  719. if (a.Length < _size)
  720. {
  721. a = new Object[_size]; //(Object[])Array.newInstance(a.getClass().getComponentType(), _size);
  722. }
  723. int i = 0;
  724. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  725. {
  726. a[i++] = (Object)elt.value();
  727. }
  728. if (a.Length > _size)
  729. {
  730. a[_size] = default(Object); // should we null out the rest of the array also? java.util.LinkedList doesn't
  731. }
  732. return a;
  733. }
  734. /**
  735. * Returns a {@link String} representation of this list, suitable for debugging.
  736. * @return a {@link String} representation of this list, suitable for debugging.
  737. */
  738. public override String ToString()
  739. {
  740. java.lang.StringBuffer buf = new java.lang.StringBuffer();
  741. buf.append("[");
  742. for (Listable elt = _head.next(), past = null; null != elt && past != _head.prev(); elt = (past = elt).next())
  743. {
  744. if (_head.next() != elt)
  745. {
  746. buf.append(", ");
  747. }
  748. buf.append(elt.value());
  749. }
  750. buf.append("]");
  751. return buf.toString();
  752. }
  753. /**
  754. * Returns a fail-fast sublist.
  755. * @see List#subList(int,int)
  756. */
  757. public virtual java.util.List<Object> subList(int i, int j)
  758. {
  759. if (i < 0 || j > _size || i > j)
  760. {
  761. throw new java.lang.IndexOutOfBoundsException();
  762. }
  763. else if (i == 0 && j == _size)
  764. {
  765. return this;
  766. }
  767. else
  768. {
  769. return new CursorableSubList(this, i, j);
  770. }
  771. }
  772. //--- protected methods ------------------------------------------
  773. /**
  774. * Inserts a new <i>value</i> into my
  775. * list, after the specified <i>before</i> element, and before the
  776. * specified <i>after</i> element
  777. *
  778. * @return the newly created
  779. * {@link org.apache.commons.collections.CursorableLinkedList.Listable}
  780. */
  781. protected internal virtual Listable insertListable(Listable before, Listable after, Object value)
  782. {
  783. _modCount++;
  784. _size++;
  785. Listable elt = new Listable(before, after, value);
  786. if (null != before)
  787. {
  788. before.setNext(elt);
  789. }
  790. else
  791. {
  792. _head.setNext(elt);
  793. }
  794. if (null != after)
  795. {
  796. after.setPrev(elt);
  797. }
  798. else
  799. {
  800. _head.setPrev(elt);
  801. }
  802. broadcastListableInserted(elt);
  803. return elt;
  804. }
  805. /**
  806. * Removes the given
  807. * {@link org.apache.commons.collections.CursorableLinkedList.Listable}
  808. * from my list.
  809. */
  810. protected internal virtual void removeListable(Listable elt)
  811. {
  812. _modCount++;
  813. _size--;
  814. if (_head.next() == elt)
  815. {
  816. _head.setNext(elt.next());
  817. }
  818. if (null != elt.next())
  819. {
  820. elt.next().setPrev(elt.prev());
  821. }
  822. if (_head.prev() == elt)
  823. {
  824. _head.setPrev(elt.prev());
  825. }
  826. if (null != elt.prev())
  827. {
  828. elt.prev().setNext(elt.next());
  829. }
  830. broadcastListableRemoved(elt);
  831. }
  832. /**
  833. * Returns the
  834. * {@link org.apache.commons.collections.CursorableLinkedList.Listable}
  835. * at the specified index.
  836. *
  837. * @throws IndexOutOfBoundsException if index is less than zero or
  838. * greater than or equal to the size of this list.
  839. */
  840. protected internal virtual Listable getListableAt(int index)
  841. {
  842. if (index < 0 || index >= _size)
  843. {
  844. throw new java.lang.IndexOutOfBoundsException("" + index + " < 0 or " + index + " >= " + _size);
  845. }
  846. if (index <= _size / 2)
  847. {
  848. Listable elt = _head.next();
  849. for (int i = 0; i < index; i++)
  850. {
  851. elt = elt.next();
  852. }
  853. return elt;
  854. }
  855. else
  856. {
  857. Listable elt = _head.prev();
  858. for (int i = (_size - 1); i > index; i--)
  859. {
  860. elt = elt.prev();
  861. }
  862. return elt;
  863. }
  864. }
  865. /**
  866. * Registers a {@link CursorableLinkedList.Cursor} to be notified
  867. * of changes to this list.
  868. */
  869. protected virtual void registerCursor(Cursor cur)
  870. {
  871. // We take this opportunity to clean the _cursors list
  872. // of WeakReference objects to garbage-collected cursors.
  873. for (java.util.Iterator<Object> it = _cursors.iterator(); it.hasNext(); )
  874. {
  875. java.lang.refj.WeakReference<Object> refJ = (java.lang.refj.WeakReference<Object>)it.next();
  876. if (refJ.get() == null)
  877. {
  878. it.remove();
  879. }
  880. }
  881. _cursors.add(new WeakReference(cur));
  882. }
  883. /**
  884. * Removes a {@link CursorableLinkedList.Cursor} from
  885. * the set of cursors to be notified of changes to this list.
  886. */
  887. protected virtual void unregisterCursor(Cursor cur)
  888. {
  889. for (java.util.Iterator<Object> it = _cursors.iterator(); it.hasNext(); )
  890. {
  891. java.lang.refj.WeakReference<Object> refJ = (java.lang.refj.WeakReference<Object>)it.next();
  892. Cursor cursor = (Cursor)refJ.get();
  893. if (cursor == null)
  894. {
  895. // some other unrelated cursor object has been
  896. // garbage-collected; let's take the opportunity to
  897. // clean up the cursors list anyway..
  898. it.remove();
  899. }
  900. else if (cursor == cur)
  901. {
  902. refJ.clear();
  903. it.remove();
  904. break;
  905. }
  906. }
  907. }
  908. /**
  909. * Informs all of my registered cursors that they are now
  910. * invalid.
  911. */
  912. protected virtual void invalidateCursors()
  913. {
  914. java.util.Iterator<Object> it = _cursors.iterator();
  915. while (it.hasNext())
  916. {
  917. java.lang.refj.WeakReference<Object> refJ = (java.lang.refj.WeakReference<Object>)it.next();
  918. Cursor cursor = (Cursor)refJ.get();
  919. if (cursor != null)
  920. {
  921. // cursor is null if object has been garbage-collected
  922. cursor.invalidate();
  923. refJ.clear();
  924. }
  925. it.remove();
  926. }
  927. }
  928. /**
  929. * Informs all of my registered cursors that the specified
  930. * element was changed.
  931. * @see #set(int,java.lang.Object)
  932. */
  933. protected virtual void broadcastListableChanged(Listable elt)
  934. {
  935. java.util.Iterator<Object> it = _cursors.iterator();
  936. while (it.hasNext())
  937. {
  938. java.lang.refj.WeakReference<Object> refJ = (java.lang.refj.WeakReference<Object>)it.next();
  939. Cursor cursor = (Cursor)refJ.get();
  940. if (cursor == null)
  941. {
  942. it.remove(); // clean up list
  943. }
  944. else
  945. {
  946. cursor.listableChanged(elt);
  947. }
  948. }
  949. }
  950. /**
  951. * Informs all of my registered cursors that the specified
  952. * element was just removed from my list.
  953. */
  954. protected virtual void broadcastListableRemoved(Listable elt)
  955. {
  956. java.util.Iterator<Object> it = _cursors.iterator();
  957. while (it.hasNext())
  958. {
  959. java.lang.refj.WeakReference<Object> refJ = (java.lang.refj.WeakReference<Object>)it.next();
  960. Cursor cursor = (Cursor)refJ.get();
  961. if (cursor == null)
  962. {
  963. it.remove(); // clean up list
  964. }
  965. else
  966. {
  967. cursor.listableRemoved(elt);
  968. }
  969. }
  970. }
  971. /**
  972. * Informs all of my registered cursors that the specified
  973. * element was just added to my list.
  974. */
  975. protected virtual void broadcastListableInserted(Listable elt)
  976. {
  977. java.util.Iterator<Object> it = _cursors.iterator();
  978. while (it.hasNext())
  979. {
  980. java.lang.refj.WeakReference<Object> refj = (java.lang.refj.WeakReference<Object>)it.next();
  981. Cursor cursor = (Cursor)refj.get();
  982. if (cursor == null)
  983. {
  984. it.remove(); // clean up list
  985. }
  986. else
  987. {
  988. cursor.listableInserted(elt);
  989. }
  990. }
  991. }
  992. private void writeObject(java.io.ObjectOutputStream outJ)
  993. {//throws IOException {
  994. outJ.defaultWriteObject();
  995. outJ.writeInt(_size);
  996. Listable cur = _head.next();
  997. while (cur != null)
  998. {
  999. outJ.writeObject(cur.value());
  1000. cur = cur.next();
  1001. }
  1002. }
  1003. private void readObject(java.io.ObjectInputStream inJ)
  1004. {//throws IOException, ClassNotFoundException {
  1005. inJ.defaultReadObject();
  1006. _size = 0;
  1007. _modCount = 0;
  1008. _cursors = new java.util.ArrayList<Object>();
  1009. _head = new Listable(null, null, null);
  1010. int size = inJ.readInt();
  1011. for (int i = 0; i < size; i++)
  1012. {
  1013. this.add(inJ.readObject());
  1014. }
  1015. }
  1016. //--- protected attributes ---------------------------------------
  1017. /** The number of elements in me. */
  1018. [NonSerialized]
  1019. protected int _size = 0;
  1020. /**
  1021. * A sentry node.
  1022. * <p>
  1023. * <tt>_head.next()</tt> points to the first element in the list,
  1024. * <tt>_head.prev()</tt> to the last. Note that it is possible for
  1025. * <tt>_head.next().prev()</tt> and <tt>_head.prev().next()</tt> to be
  1026. * non-null, as when I am a sublist for some larger list.
  1027. * Use <tt>== _head.next()</tt> and <tt>== _head.prev()</tt> to determine
  1028. * if a given
  1029. * {@link org.apache.commons.collections.CursorableLinkedList.Listable}
  1030. * is the first or last element in the list.
  1031. */
  1032. [NonSerialized]
  1033. protected Listable _head = new Listable(null, null, null);
  1034. /** Tracks the number of structural modifications to me. */
  1035. [NonSerialized]
  1036. protected internal int _modCount = 0;
  1037. /**
  1038. * A list of the currently {@link CursorableLinkedList.Cursor}s currently
  1039. * open in this list.
  1040. */
  1041. [NonSerialized]
  1042. protected java.util.List<Object> _cursors = new java.util.ArrayList<Object>();
  1043. //--- inner classes ----------------------------------------------
  1044. [Serializable]
  1045. public class Listable : java.io.Serializable
  1046. {
  1047. private Listable _prev = null;
  1048. private Listable _next = null;
  1049. private Object _val = null;
  1050. internal Listable(Listable prev, Listable next, Object val)
  1051. {
  1052. _prev = prev;
  1053. _next = next;
  1054. _val = val;
  1055. }
  1056. internal virtual Listable next()
  1057. {
  1058. return _next;
  1059. }
  1060. internal virtual Listable prev()
  1061. {
  1062. return _prev;
  1063. }
  1064. internal virtual Object value()
  1065. {
  1066. return _val;
  1067. }
  1068. internal virtual void setNext(Listable next)
  1069. {
  1070. _next = next;
  1071. }
  1072. internal virtual void setPrev(Listable prev)
  1073. {
  1074. _prev = prev;
  1075. }
  1076. internal virtual Object setValue(Object val)
  1077. {
  1078. Object temp = _val;
  1079. _val = val;
  1080. return temp;
  1081. }
  1082. }
  1083. public class ListIter : java.util.ListIterator<Object>
  1084. {
  1085. private readonly CursorableLinkedList root;
  1086. public Listable _cur = null;
  1087. protected internal Listable _lastReturned = null;
  1088. protected int _expectedModCount;// = _modCount;
  1089. protected int _nextIndex = 0;
  1090. internal ListIter(int index, CursorableLinkedList root)
  1091. {
  1092. this.root = root;
  1093. this._expectedModCount = root._modCount;
  1094. if (index == 0)
  1095. {
  1096. _cur = new Listable(null, root._head.next(), null);
  1097. _nextIndex = 0;
  1098. }
  1099. else if (index == root._size)
  1100. {
  1101. _cur = new Listable(root._head.prev(), null, null);
  1102. _nextIndex = root._size;
  1103. }
  1104. else
  1105. {
  1106. Listable temp = root.getListableAt(index);
  1107. _cur = new Listable(temp.prev(), temp, null);
  1108. _nextIndex = index;
  1109. }
  1110. }
  1111. public virtual Object previous()
  1112. {
  1113. checkForComod();
  1114. if (!hasPrevious())
  1115. {
  1116. throw new java.util.NoSuchElementException();
  1117. }
  1118. else
  1119. {
  1120. Object ret = _cur.prev().value();
  1121. _lastReturned = _cur.prev();
  1122. _cur.setNext(_cur.prev());
  1123. _cur.setPrev(_cur.prev().prev());
  1124. _nextIndex--;
  1125. return ret;
  1126. }
  1127. }
  1128. public virtual bool hasNext()
  1129. {
  1130. checkForComod();
  1131. return (null != _cur.next() && _cur.prev() != root._head.prev());
  1132. }
  1133. public virtual Object next()
  1134. {
  1135. checkForComod();
  1136. if (!hasNext())
  1137. {
  1138. throw new java.util.NoSuchElementException();
  1139. }
  1140. else
  1141. {
  1142. Object ret = _cur.next().value();
  1143. _lastReturned = _cur.next();
  1144. _cur.setPrev(_cur.next());
  1145. _cur.setNext(_cur.next().next());
  1146. _nextIndex++;
  1147. return ret;
  1148. }
  1149. }
  1150. public virtual int previousIndex()
  1151. {
  1152. checkForComod();
  1153. if (!hasPrevious())
  1154. {
  1155. return -1;
  1156. }
  1157. return _nextIndex - 1;
  1158. }
  1159. public virtual bool hasPrevious()
  1160. {
  1161. checkForComod();
  1162. return (null != _cur.prev() && _cur.next() != root._head.next());
  1163. }
  1164. public virtual void set(Object o)
  1165. {
  1166. checkForComod();
  1167. try
  1168. {
  1169. _lastReturned.setValue(o);
  1170. }
  1171. catch (java.lang.NullPointerException e)
  1172. {
  1173. throw new java.lang.IllegalStateException(e); // Basties note: giving more informations
  1174. }
  1175. }
  1176. public virtual int nextIndex()
  1177. {
  1178. checkForComod();
  1179. if (!hasNext())
  1180. {
  1181. return root.size();
  1182. }
  1183. return _nextIndex;
  1184. }
  1185. public virtual void remove()
  1186. {
  1187. checkForComod();
  1188. if (null == _lastReturned)
  1189. {
  1190. throw new java.lang.IllegalStateException();
  1191. }
  1192. else
  1193. {
  1194. _cur.setNext(_lastReturned == root._head.prev() ? null : _lastReturned.next());
  1195. _cur.setPrev(_lastReturned == root._head.next() ? null : _lastReturned.prev());
  1196. root.removeListable(_lastReturned);
  1197. _lastReturned = null;
  1198. _nextIndex--;
  1199. _expectedModCount++;
  1200. }
  1201. }
  1202. public virtual void add(Object o)
  1203. {
  1204. checkForComod();
  1205. _cur.setPrev(root.insertListable(_cur.prev(), _cur.next(), o));
  1206. _lastReturned = null;
  1207. _nextIndex++;
  1208. _expectedModCount++;
  1209. }
  1210. protected virtual void checkForComod()
  1211. {
  1212. if (_expectedModCount != root._modCount)
  1213. {
  1214. throw new java.util.ConcurrentModificationException();
  1215. }
  1216. }
  1217. }
  1218. public class Cursor : ListIter, java.util.ListIterator<Object>
  1219. {
  1220. bool _valid = false;
  1221. private CursorableLinkedList root;
  1222. internal Cursor(int index, CursorableLinkedList root)
  1223. : base(index, root)
  1224. {
  1225. this.root = root;
  1226. _valid = true;
  1227. root.registerCursor(this);
  1228. }
  1229. public override int previousIndex()
  1230. {
  1231. throw new java.lang.UnsupportedOperationException();
  1232. }
  1233. public override int nextIndex()
  1234. {
  1235. throw new java.lang.UnsupportedOperationException();
  1236. }
  1237. public override void add(Object o)
  1238. {
  1239. checkForComod();
  1240. Listable elt = root.insertListable(_cur.prev(), _cur.next(), o);
  1241. _cur.setPrev(elt);
  1242. _cur.setNext(elt.next());
  1243. _lastReturned = null;
  1244. _nextIndex++;
  1245. _expectedModCount++;
  1246. }
  1247. protected internal virtual void listableRemoved(Listable elt)
  1248. {
  1249. if (null == root._head.prev())
  1250. {
  1251. _cur.setNext(null);
  1252. }
  1253. else if (_cur.next() == elt)
  1254. {
  1255. _cur.setNext(elt.next());
  1256. }
  1257. if (null == root._head.next())
  1258. {
  1259. _cur.setPrev(null);
  1260. }
  1261. else if (_cur.prev() == elt)
  1262. {
  1263. _cur.setPrev(elt.prev());
  1264. }
  1265. if (_lastReturned == elt)
  1266. {
  1267. _lastReturned = null;
  1268. }
  1269. }
  1270. protected internal virtual void listableInserted(Listable elt)
  1271. {
  1272. if (null == _cur.next() && null == _cur.prev())
  1273. {
  1274. _cur.setNext(elt);
  1275. }
  1276. else if (_cur.prev() == elt.prev())
  1277. {
  1278. _cur.setNext(elt);
  1279. }
  1280. if (_cur.next() == elt.next())
  1281. {
  1282. _cur.setPrev(elt);
  1283. }
  1284. if (_lastReturned == elt)
  1285. {
  1286. _lastReturned = null;
  1287. }
  1288. }
  1289. protected internal virtual void listableChanged(Listable elt)
  1290. {
  1291. if (_lastReturned == elt)
  1292. {
  1293. _lastReturned = null;
  1294. }
  1295. }
  1296. protected override void checkForComod()
  1297. {
  1298. if (!_valid)
  1299. {
  1300. throw new java.util.ConcurrentModificationException();
  1301. }
  1302. }
  1303. protected internal void invalidate()
  1304. {
  1305. _valid = false;
  1306. }
  1307. /**
  1308. * Mark this cursor as no longer being needed. Any resources
  1309. * associated with this cursor are immediately released.
  1310. * In previous versions of this class, it was mandatory to close
  1311. * all cursor objects to avoid memory leaks. It is <i>no longer</i>
  1312. * necessary to call this close method; an instance of this class
  1313. * can now be treated exactly like a normal iterator.
  1314. */
  1315. public void close()
  1316. {
  1317. if (_valid)
  1318. {
  1319. _valid = false;
  1320. root.unregisterCursor(this);
  1321. }
  1322. }
  1323. }
  1324. }
  1325. /**
  1326. * @deprecated Use new version in list subpackage, which has been rewritten
  1327. * and now returns the cursor from the listIterator method. Will be removed in v4.0
  1328. */
  1329. class CursorableSubList : CursorableLinkedList, java.util.List<Object>
  1330. {
  1331. //--- constructors -----------------------------------------------
  1332. internal Cursorable