File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\util\Iterators.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.util;
25
26 import com.google.common.base.Predicates;
27
28 import java.util.Collections;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.NoSuchElementException;
32 import java.util.ListIterator;
33 import java.util.AbstractList;
34 import java.util.Arrays;
35 import java.util.Set;
36 import java.util.HashSet;
37
38 /**
39 * Varios {@link Iterator} implementations.
40 *
41 * @author Kohsuke Kawaguchi
42 * @see AdaptedIterator
43 */
44 public class Iterators {
45 /**
46 * Returns the empty iterator.
47 */
48 public static <T> Iterator<T> empty() {
49 return Collections.<T>emptyList().iterator();
50 }
51
52 /**
53 * Produces {A,B,C,D,E,F} from {{A,B},{C},{},{D,E,F}}.
54 */
55 public static abstract class FlattenIterator<U,T> implements Iterator<U> {
56 private final Iterator<? extends T> core;
57 private Iterator<U> cur;
58
59 protected FlattenIterator(Iterator<? extends T> core) {
60 this.core = core;
61 cur = Collections.<U>emptyList().iterator();
62 }
63
64 protected FlattenIterator(Iterable<? extends T> core) {
65 this(core.iterator());
66 }
67
68 protected abstract Iterator<U> expand(T t);
69
70 public boolean hasNext() {
71 while(!cur.hasNext()) {
72 if(!core.hasNext())
73 return false;
74 cur = expand(core.next());
75 }
76 return true;
77 }
78
79 public U next() {
80 if(!hasNext()) throw new NoSuchElementException();
81 return cur.next();
82 }
83
84 public void remove() {
85 throw new UnsupportedOperationException();
86 }
87 }
88
89 /**
90 * Creates a filtered view of another iterator.
91 *
92 * @since 1.150
93 */
94 public static abstract class FilterIterator<T> implements Iterator<T> {
95 private final Iterator<? extends T> core;
96 private T next;
97 private boolean fetched;
98
99 protected FilterIterator(Iterator<? extends T> core) {
100 this.core = core;
101 }
102
103 protected FilterIterator(Iterable<? extends T> core) {
104 this(core.iterator());
105 }
106
107 private void fetch() {
108 while(!fetched && core.hasNext()) {
109 T n = core.next();
110 if(filter(n)) {
111 next = n;
112 fetched = true;
113 }
114 }
115 }
116
117 /**
118 * Filter out items in the original collection.
119 *
120 * @return
121 * true to leave this item and return this item from this iterator.
122 * false to hide this item.
123 */
124 protected abstract boolean filter(T t);
125
126 public boolean hasNext() {
127 fetch();
128 return fetched;
129 }
130
131 public T next() {
132 fetch();
133 if(!fetched) throw new NoSuchElementException();
134 fetched = false;
135 return next;
136 }
137
138 public void remove() {
139 core.remove();
140 }
141 }
142
143 /**
144 * Remove duplicates from another iterator.
145 */
146 public static final class DuplicateFilterIterator<T> extends FilterIterator<T> {
147 private final Set<T> seen = new HashSet<T>();
148
149 public DuplicateFilterIterator(Iterator<? extends T> core) {
150 super(core);
151 }
152
153 public DuplicateFilterIterator(Iterable<? extends T> core) {
154 super(core);
155 }
156
157 protected boolean filter(T t) {
158 return seen.add(t);
159 }
160 }
161
162 /**
163 * Returns the {@link Iterable} that lists items in the reverse order.
164 *
165 * @since 1.150
166 */
167 public static <T> Iterable<T> reverse(final List<T> lst) {
168 return new Iterable<T>() {
169 public Iterator<T> iterator() {
170 final ListIterator<T> itr = lst.listIterator(lst.size());
171 return new Iterator<T>() {
172 public boolean hasNext() {
173 return itr.hasPrevious();
174 }
175
176 public T next() {
177 return itr.previous();
178 }
179
180 public void remove() {
181 itr.remove();
182 }
183 };
184 }
185 };
186 }
187
188 /**
189 * Returns an {@link Iterable} that lists items in the normal order
190 * but which hides the base iterator implementation details.
191 *
192 * @since 1.492
193 */
194 public static <T> Iterable<T> wrap(final Iterable<T> base) {
195 return new Iterable<T>() {
196 public Iterator<T> iterator() {
197 final Iterator<T> itr = base.iterator();
198 return new Iterator<T>() {
199 public boolean hasNext() {
200 return itr.hasNext();
201 }
202
203 public T next() {
204 return itr.next();
205 }
206
207 public void remove() {
208 itr.remove();
209 }
210 };
211 }
212 };
213 }
214
215 /**
216 * Returns a list that represents [start,end).
217 *
218 * For example sequence(1,5,1)={1,2,3,4}, and sequence(7,1,-2)={7.5,3}
219 *
220 * @since 1.150
221 */
222 public static List<Integer> sequence(final int start, int end, final int step) {
223
224 final int size = (end-start)/step;
225 if(size<0) throw new IllegalArgumentException("List size is negative");
226
227 return new AbstractList<Integer>() {
228 public Integer get(int index) {
229 if(index<0 || index>=size)
230 throw new IndexOutOfBoundsException();
231 return start+index*step;
232 }
233
234 public int size() {
235 return size;
236 }
237 };
238 }
239
240 public static List<Integer> sequence(int start, int end) {
241 return sequence(start,end,1);
242 }
243
244 /**
245 * The short cut for {@code reverse(sequence(start,end,step))}.
246 *
247 * @since 1.150
248 */
249 public static List<Integer> reverseSequence(int start, int end, int step) {
250 return sequence(end-1,start-1,-step);
251 }
252
253 public static List<Integer> reverseSequence(int start, int end) {
254 return reverseSequence(start,end,1);
255 }
256
257 /**
258 * Casts {@link Iterator} by taking advantage of its covariant-ness.
259 */
260 @SuppressWarnings({"unchecked"})
261 public static <T> Iterator<T> cast(Iterator<? extends T> itr) {
262 return (Iterator)itr;
263 }
264
265 /**
266 * Casts {@link Iterable} by taking advantage of its covariant-ness.
267 */
268 @SuppressWarnings({"unchecked"})
269 public static <T> Iterable<T> cast(Iterable<? extends T> itr) {
270 return (Iterable)itr;
271 }
272
273 /**
274 * Returns an {@link Iterator} that only returns items of the given subtype.
275 */
276 @SuppressWarnings({"unchecked"})
277 public static <U,T extends U> Iterator<T> subType(Iterator<U> itr, final Class<T> type) {
278 return (Iterator)new FilterIterator<U>(itr) {
279 protected boolean filter(U u) {
280 return type.isInstance(u);
281 }
282 };
283 }
284
285 /**
286 * Creates a read-only mutator that disallows {@link Iterator#remove()}.
287 */
288 public static <T> Iterator<T> readOnly(final Iterator<T> itr) {
289 return new Iterator<T>() {
290 public boolean hasNext() {
291 return itr.hasNext();
292 }
293
294 public T next() {
295 return itr.next();
296 }
297
298 public void remove() {
299 throw new UnsupportedOperationException();
300 }
301 };
302 }
303
304 /**
305 * Wraps another iterator and throws away nulls.
306 */
307 public static <T> Iterator<T> removeNull(final Iterator<T> itr) {
308 return com.google.common.collect.Iterators.filter(itr, Predicates.notNull());
309 }
310
311 /**
312 * Returns an {@link Iterable} that iterates over all the given {@link Iterable}s.
313 *
314 * <p>
315 * That is, this creates {A,B,C,D} from {A,B},{C,D}.
316 */
317 public static <T> Iterable<T> sequence( final Iterable<? extends T>... iterables ) {
318 return new Iterable<T>() {
319 public Iterator<T> iterator() {
320 return new FlattenIterator<T,Iterable<? extends T>>(Arrays.asList(iterables)) {
321 protected Iterator<T> expand(Iterable<? extends T> iterable) {
322 return cast(iterable).iterator();
323 }
324 };
325 }
326 };
327 }
328
329 /**
330 * Filters another iterator by eliminating duplicates.
331 */
332 public static <T> Iterator<T> removeDups(Iterator<T> iterator) {
333 return new FilterIterator<T>(iterator) {
334 final Set<T> found = new HashSet<T>();
335 @Override
336 protected boolean filter(T t) {
337 return found.add(t);
338 }
339 };
340 }
341
342 /**
343 * Filters another iterator by eliminating duplicates.
344 */
345 public static <T> Iterable<T> removeDups(final Iterable<T> base) {
346 return new Iterable<T>() {
347 public Iterator<T> iterator() {
348 return removeDups(base.iterator());
349 }
350 };
351 }
352
353 public static <T> Iterator<T> sequence(Iterator<? extends T>... iterators) {
354 return com.google.common.collect.Iterators.concat(iterators);
355 }
356
357 /**
358 * Returns the elements in the base iterator until it hits any element that doesn't satisfy the filter.
359 * Then the rest of the elements in the base iterator gets ignored.
360 *
361 * @since 1.485
362 */
363 public static <T> Iterator<T> limit(final Iterator<? extends T> base, final CountingPredicate<? super T> filter) {
364 return new Iterator<T>() {
365 private T next;
366 private boolean end;
367 private int index=0;
368 public boolean hasNext() {
369 fetch();
370 return next!=null;
371 }
372
373 public T next() {
374 fetch();
375 T r = next;
376 next = null;
377 return r;
378 }
379
380 private void fetch() {
381 if (next==null && !end) {
382 if (base.hasNext()) {
383 next = base.next();
384 if (!filter.apply(index++,next)) {
385 next = null;
386 end = true;
387 }
388 } else {
389 end = true;
390 }
391 }
392 }
393
394 public void remove() {
395 throw new UnsupportedOperationException();
396 }
397 };
398 }
399
400 public interface CountingPredicate<T> {
401 boolean apply(int index, T input);
402 }
403 }
404