File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\util\RunList.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.Predicate;
27 import com.google.common.collect.Iterables;
28 import com.google.common.collect.Iterators;
29 import hudson.model.AbstractBuild;
30 import hudson.model.Item;
31 import hudson.model.Job;
32 import hudson.model.Node;
33 import hudson.model.Result;
34 import hudson.model.Run;
35 import hudson.model.View;
36 import hudson.util.Iterators.CountingPredicate;
37
38 import java.util.AbstractList;
39 import java.util.ArrayList;
40 import java.util.Calendar;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Comparator;
44 import java.util.GregorianCalendar;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.NoSuchElementException;
48
49 /**
50 * {@link List} of {@link Run}s, sorted in the descending date order.
51 *
52 * @author Kohsuke Kawaguchi
53 */
54 public class RunList<R extends Run> extends AbstractList<R> {
55
56 private Iterable<R> base;
57
58 private R first;
59 private Integer size;
60
61 public RunList() {
62 base = Collections.emptyList();
63 }
64
65 public RunList(Job j) {
66 base = j.getBuilds();
67 }
68
69 public RunList(View view) {// this is a type unsafe operation
70 List<Iterable<R>> jobs = new ArrayList<Iterable<R>>();
71 for (Item item : view.getItems())
72 for (Job<?,?> j : item.getAllJobs())
73 jobs.add(((Job)j).getBuilds());
74
75 this.base = combine(jobs);
76 }
77
78 public RunList(Collection<? extends Job> jobs) {
79 List<Iterable<R>> src = new ArrayList<Iterable<R>>();
80 for (Job j : jobs)
81 src.add(j.getBuilds());
82 this.base = combine(src);
83 }
84
85 private Iterable<R> combine(Iterable<Iterable<R>> jobs) {
86 return Iterables.mergeSorted(jobs, new Comparator<R>() {
87 public int compare(R o1, R o2) {
88 long lhs = o1.getTimeInMillis();
89 long rhs = o2.getTimeInMillis();
90 if (lhs > rhs) return -1;
91 if (lhs < rhs) return 1;
92 return 0;
93 }
94 });
95 }
96
97 private RunList(Iterable<R> c) {
98 base = c;
99 }
100
101 @Override
102 public Iterator<R> iterator() {
103 return base.iterator();
104 }
105
106 /**
107 * @deprecated as of 1.485
108 * {@link RunList}, despite its name, should be really used as {@link Iterable}, not as {@link List}.
109 */
110 @Override
111 public int size() {
112 if (size==null) {
113 int sz=0;
114 for (R r : this) {
115 first = r;
116 sz++;
117 }
118 size = sz;
119 }
120 return size;
121 }
122
123 /**
124 * @deprecated as of 1.485
125 * {@link RunList}, despite its name, should be really used as {@link Iterable}, not as {@link List}.
126 */
127 @Override
128 public R get(int index) {
129 return Iterators.get(iterator(),index);
130 }
131
132 /**
133 * {@link AbstractList#subList(int, int)} isn't very efficient on our {@link Iterable} based implementation.
134 * In fact the range check alone would require us to iterate all the elements,
135 * so we'd be better off just copying into ArrayList.
136 */
137 @Override
138 public List<R> subList(int fromIndex, int toIndex) {
139 List<R> r = new ArrayList<R>();
140 Iterator<R> itr = iterator();
141 Iterators.skip(itr,fromIndex);
142 for (int i=toIndex-fromIndex; i>0; i--) {
143 r.add(itr.next());
144 }
145 return r;
146 }
147
148 @Override
149 public int indexOf(Object o) {
150 int index=0;
151 for (R r : this) {
152 if (r.equals(o))
153 return index;
154 index++;
155 }
156 return -1;
157 }
158
159 @Override
160 public int lastIndexOf(Object o) {
161 int a = -1;
162 int index=0;
163 for (R r : this) {
164 if (r.equals(o))
165 a = index;
166 index++;
167 }
168 return a;
169 }
170
171 @Override
172 public boolean isEmpty() {
173 return !iterator().hasNext();
174 }
175
176 public R getFirstBuild() {
177 size();
178 return first;
179 }
180
181 public R getLastBuild() {
182 Iterator<R> itr = iterator();
183 return itr.hasNext() ? itr.next() : null;
184 }
185
186 public static <R extends Run>
187 RunList<R> fromRuns(Collection<? extends R> runs) {
188 return new RunList<R>((Iterable)runs);
189 }
190
191 /**
192 * Returns elements that satisfy the given predicate.
193 */
194 // for compatibility reasons, this method doesn't create a new list but updates the current one
195 private RunList<R> filter(Predicate<R> predicate) {
196 size = null;
197 first = null;
198 base = Iterables.filter(base,predicate);
199 return this;
200 }
201
202 /**
203 * Returns the first streak of the elements that satisfy the given predicate.
204 *
205 * For example, {@code filter([1,2,3,4],odd)==[1,3]} but {@code limit([1,2,3,4],odd)==[1]}.
206 */
207 private RunList<R> limit(final CountingPredicate<R> predicate) {
208 size = null;
209 first = null;
210 final Iterable<R> nested = base;
211 base = new Iterable<R>() {
212 public Iterator<R> iterator() {
213 return hudson.util.Iterators.limit(nested.iterator(),predicate);
214 }
215
216 @Override
217 public String toString() {
218 return Iterables.toString(this);
219 }
220 };
221 return this;
222 }
223
224 /**
225 * Filter the list to non-successful builds only.
226 */
227 public RunList<R> failureOnly() {
228 return filter(new Predicate<R>() {
229 public boolean apply(R r) {
230 return r.getResult()!=Result.SUCCESS;
231 }
232 });
233 }
234
235 /**
236 * Filter the list to builds on a single node only
237 */
238 public RunList<R> node(final Node node) {
239 return filter(new Predicate<R>() {
240 public boolean apply(R r) {
241 return (r instanceof AbstractBuild) && ((AbstractBuild)r).getBuiltOn()==node;
242 }
243 });
244 }
245
246 /**
247 * Filter the list to regression builds only.
248 */
249 public RunList<R> regressionOnly() {
250 return filter(new Predicate<R>() {
251 public boolean apply(R r) {
252 return r.getBuildStatusSummary().isWorse;
253 }
254 });
255 }
256
257 /**
258 * Filter the list by timestamp.
259 *
260 * {@code s&lt=;e}.
261 */
262 public RunList<R> byTimestamp(final long start, final long end) {
263 return
264 limit(new CountingPredicate<R>() {
265 public boolean apply(int index,R r) {
266 return r.getTimeInMillis()<end;
267 }
268 }).filter(new Predicate<R>() {
269 public boolean apply(R r) {
270 return start<=r.getTimeInMillis();
271 }
272 });
273 }
274
275 /**
276 * Reduce the size of the list by only leaving relatively new ones.
277 * This also removes on-going builds, as RSS cannot be used to publish information
278 * if it changes.
279 */
280 public RunList<R> newBuilds() {
281 GregorianCalendar cal = new GregorianCalendar();
282 cal.add(Calendar.DAY_OF_YEAR, -7);
283 final long t = cal.getTimeInMillis();
284
285 // can't publish on-going builds
286 return filter(new Predicate<R>() {
287 public boolean apply(R r) {
288 return !r.isBuilding();
289 }
290 })
291 // put at least 10 builds, but otherwise ignore old builds
292 .limit(new CountingPredicate<R>() {
293 public boolean apply(int index, R r) {
294 return index < 10 || r.getTimeInMillis() >= t;
295 }
296 });
297 }
298 }
299