PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/gadfly/nofs
C# | 317 lines | 133 code | 24 blank | 160 comment | 16 complexity | 50e8bae997aa0fbb613e3443e0528d2a 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. using org.apache.commons.collections.list;
  18. namespace org.apache.commons.collections.iterators
  19. {
  20. /**
  21. * An IteratorChain is an Iterator that wraps a number of Iterators.
  22. * <p>
  23. * This class makes multiple iterators look like one to the caller
  24. * When any method from the Iterator interface is called, the IteratorChain
  25. * will delegate to a single underlying Iterator. The IteratorChain will
  26. * invoke the Iterators in sequence until all Iterators are exhausted.
  27. * <p>
  28. * Under many circumstances, linking Iterators together in this manner is
  29. * more efficient (and convenient) than reading out the contents of each
  30. * Iterator into a List and creating a new Iterator.
  31. * <p>
  32. * Calling a method that adds new Iterator<i>after a method in the Iterator
  33. * interface has been called</i> will result in an UnsupportedOperationException.
  34. * Subclasses should <i>take care</i> to not alter the underlying List of Iterators.
  35. * <p>
  36. * NOTE: As from version 3.0, the IteratorChain may contain no
  37. * iterators. In this case the class will function as an empty iterator.
  38. *
  39. * @since Commons Collections 2.1
  40. * @version $Revision$ $Date$
  41. *
  42. * @author Morgan Delagrange
  43. * @author Stephen Colebourne
  44. */
  45. public class IteratorChain : java.util.Iterator<Object>
  46. {
  47. /** The chain of iterators */
  48. protected readonly java.util.List<Object> iteratorChain = new java.util.ArrayList<Object>();
  49. /** The index of the current iterator */
  50. protected int currentIteratorIndex = 0;
  51. /** The current iterator */
  52. protected java.util.Iterator<Object> currentIterator = null;
  53. /**
  54. * The "last used" Iterator is the Iterator upon which
  55. * next() or hasNext() was most recently called
  56. * used for the remove() operation only
  57. */
  58. protected java.util.Iterator<Object> lastUsedIterator = null;
  59. /**
  60. * ComparatorChain is "locked" after the first time
  61. * compare(Object,Object) is called
  62. */
  63. protected bool isLockedJ = false;
  64. //-----------------------------------------------------------------------
  65. /**
  66. * Construct an IteratorChain with no Iterators.
  67. * <p>
  68. * You will normally use {@link #addIterator(Iterator)} to add
  69. * some iterators after using this constructor.
  70. */
  71. public IteratorChain()
  72. : base()
  73. {
  74. }
  75. /**
  76. * Construct an IteratorChain with a single Iterator.
  77. *
  78. * @param iterator first Iterator in the IteratorChain
  79. * @throws NullPointerException if the iterator is null
  80. */
  81. public IteratorChain(java.util.Iterator<Object> iterator)
  82. : base()
  83. {
  84. addIterator(iterator);
  85. }
  86. /**
  87. * Constructs a new <code>IteratorChain</code> over the two
  88. * given iterators.
  89. *
  90. * @param a the first child iterator
  91. * @param b the second child iterator
  92. * @throws NullPointerException if either iterator is null
  93. */
  94. public IteratorChain(java.util.Iterator<Object> a, java.util.Iterator<Object> b)
  95. : base()
  96. {
  97. addIterator(a);
  98. addIterator(b);
  99. }
  100. /**
  101. * Constructs a new <code>IteratorChain</code> over the array
  102. * of iterators.
  103. *
  104. * @param iterators the array of iterators
  105. * @throws NullPointerException if iterators array is or contains null
  106. */
  107. public IteratorChain(java.util.Iterator<Object>[] iterators)
  108. : base()
  109. {
  110. for (int i = 0; i < iterators.Length; i++)
  111. {
  112. addIterator(iterators[i]);
  113. }
  114. }
  115. /**
  116. * Constructs a new <code>IteratorChain</code> over the collection
  117. * of iterators.
  118. *
  119. * @param iterators the collection of iterators
  120. * @throws NullPointerException if iterators collection is or contains null
  121. * @throws ClassCastException if iterators collection doesn't contain an iterator
  122. */
  123. public IteratorChain(java.util.Collection<Object> iterators)
  124. : base()
  125. {
  126. for (java.util.Iterator<Object> it = iterators.iterator(); it.hasNext(); )
  127. {
  128. java.util.Iterator<Object> item = (java.util.Iterator<Object>)it.next();
  129. addIterator(item);
  130. }
  131. }
  132. //-----------------------------------------------------------------------
  133. /**
  134. * Add an Iterator to the end of the chain
  135. *
  136. * @param iterator Iterator to add
  137. * @throws IllegalStateException if I've already started iterating
  138. * @throws NullPointerException if the iterator is null
  139. */
  140. public void addIterator(java.util.Iterator<Object> iterator)
  141. {
  142. checkLocked();
  143. if (iterator == null)
  144. {
  145. throw new java.lang.NullPointerException("Iterator must not be null");
  146. }
  147. iteratorChain.add(iterator);
  148. }
  149. /**
  150. * Set the Iterator at the given index
  151. *
  152. * @param index index of the Iterator to replace
  153. * @param iterator Iterator to place at the given index
  154. * @throws IndexOutOfBoundsException if index &lt; 0 or index &gt; size()
  155. * @throws IllegalStateException if I've already started iterating
  156. * @throws NullPointerException if the iterator is null
  157. */
  158. public void setIterator(int index, java.util.Iterator<Object> iterator)
  159. {//throws IndexOutOfBoundsException {
  160. checkLocked();
  161. if (iterator == null)
  162. {
  163. throw new java.lang.NullPointerException("Iterator must not be null");
  164. }
  165. iteratorChain.set(index, iterator);
  166. }
  167. /**
  168. * Get the list of Iterators (unmodifiable)
  169. *
  170. * @return the unmodifiable list of iterators added
  171. */
  172. public java.util.List<Object> getIterators()
  173. {
  174. return UnmodifiableList.decorate(iteratorChain);
  175. }
  176. /**
  177. * Number of Iterators in the current IteratorChain.
  178. *
  179. * @return Iterator count
  180. */
  181. public int size()
  182. {
  183. return iteratorChain.size();
  184. }
  185. /**
  186. * Determine if modifications can still be made to the IteratorChain.
  187. * IteratorChains cannot be modified once they have executed a method
  188. * from the Iterator interface.
  189. *
  190. * @return true if IteratorChain cannot be modified, false if it can
  191. */
  192. public bool isLocked()
  193. {
  194. return isLockedJ;
  195. }
  196. /**
  197. * Checks whether the iterator chain is now locked and in use.
  198. */
  199. private void checkLocked()
  200. {
  201. if (isLocked())
  202. {
  203. throw new java.lang.UnsupportedOperationException("IteratorChain cannot be changed after the first use of a method from the Iterator interface");
  204. }
  205. }
  206. /**
  207. * Lock the chain so no more iterators can be added.
  208. * This must be called from all Iterator interface methods.
  209. */
  210. private void lockChain()
  211. {
  212. if (!isLockedJ)
  213. {
  214. isLockedJ = true;
  215. }
  216. }
  217. /**
  218. * Updates the current iterator field to ensure that the current Iterator
  219. * is not exhausted
  220. */
  221. protected void updateCurrentIterator()
  222. {
  223. if (currentIterator == null)
  224. {
  225. if (iteratorChain.isEmpty())
  226. {
  227. currentIterator = EmptyIterator.INSTANCE;
  228. }
  229. else
  230. {
  231. currentIterator = (java.util.Iterator<Object>)iteratorChain.get(0);
  232. }
  233. // set last used iterator here, in case the user calls remove
  234. // before calling hasNext() or next() (although they shouldn't)
  235. lastUsedIterator = currentIterator;
  236. }
  237. while (currentIterator.hasNext() == false && currentIteratorIndex < iteratorChain.size() - 1)
  238. {
  239. currentIteratorIndex++;
  240. currentIterator = (java.util.Iterator<Object>)iteratorChain.get(currentIteratorIndex);
  241. }
  242. }
  243. //-----------------------------------------------------------------------
  244. /**
  245. * Return true if any Iterator in the IteratorChain has a remaining element.
  246. *
  247. * @return true if elements remain
  248. */
  249. public bool hasNext()
  250. {
  251. lockChain();
  252. updateCurrentIterator();
  253. lastUsedIterator = currentIterator;
  254. return currentIterator.hasNext();
  255. }
  256. /**
  257. * Returns the next Object of the current Iterator
  258. *
  259. * @return Object from the current Iterator
  260. * @throws java.util.NoSuchElementException if all the Iterators are exhausted
  261. */
  262. public Object next()
  263. {
  264. lockChain();
  265. updateCurrentIterator();
  266. lastUsedIterator = currentIterator;
  267. return currentIterator.next();
  268. }
  269. /**
  270. * Removes from the underlying collection the last element
  271. * returned by the Iterator. As with next() and hasNext(),
  272. * this method calls remove() on the underlying Iterator.
  273. * Therefore, this method may throw an
  274. * UnsupportedOperationException if the underlying
  275. * Iterator does not support this method.
  276. *
  277. * @throws UnsupportedOperationException
  278. * if the remove operator is not supported by the underlying Iterator
  279. * @throws IllegalStateException
  280. * if the next method has not yet been called, or the remove method has
  281. * already been called after the last call to the next method.
  282. */
  283. public void remove()
  284. {
  285. lockChain();
  286. if (currentIterator == null)
  287. {
  288. updateCurrentIterator();
  289. }
  290. lastUsedIterator.remove();
  291. }
  292. }
  293. }