提交 3c992383 编写于 作者: K kohsuke

use RunList in Job.getBuilds() as well, since it's making a copy.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@34041 71c3de6d-444a-0410-be80-ed276b4c234a
上级 c9ab4c04
......@@ -26,6 +26,7 @@ package hudson.model;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.ExtensionPoint;
import hudson.Util;
import hudson.XmlFile;
......@@ -67,10 +68,10 @@ import java.io.StringWriter;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.AbstractList;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
......@@ -585,13 +586,14 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
public abstract boolean isBuildable();
/**
* Gets all the builds.
* Gets the read-only view of all the builds.
*
* @return never null. The first entry is the latest build.
*/
@Exported
public List<RunT> getBuilds() {
return new ArrayList<RunT>(_getRuns().values());
@WithBridgeMethods(List.class)
public RunList<JobT,RunT> getBuilds() {
return RunList.fromRuns(_getRuns().values());
}
/**
......@@ -643,32 +645,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* Obtains a list of builds, in the descending order, that are within the specified time range [start,end).
*
* @return can be empty but never null.
* @deprecated
* as of 1.372. Should just do {@code getBuilds().byTimestamp(s,e)} to avoid code bloat in {@link Job}.
*/
public List<RunT> getBuildsByTimestamp(long start, long end) {
final List<RunT> builds = getBuilds();
AbstractList<Long> TIMESTAMP_ADAPTER = new AbstractList<Long>() {
public Long get(int index) {
return builds.get(index).timestamp;
}
public int size() {
return builds.size();
}
};
Comparator<Long> DESCENDING_ORDER = new Comparator<Long>() {
public int compare(Long o1, Long o2) {
if (o1 > o2) return -1;
if (o1 < o2) return +1;
return 0;
}
};
int s = Collections.binarySearch(TIMESTAMP_ADAPTER, start, DESCENDING_ORDER);
if (s<0) s=-(s+1); // min is inclusive
int e = Collections.binarySearch(TIMESTAMP_ADAPTER, end, DESCENDING_ORDER);
if (e<0) e=-(e+1); else e++; // max is exclusive, so the exact match should be excluded
return builds.subList(e,s);
@WithBridgeMethods(List.class)
public RunList<JobT,RunT> getBuildsByTimestamp(long start, long end) {
return getBuilds().byTimestamp(start,end);
}
@CLIResolver
......@@ -1364,12 +1346,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
public void doRssAll(StaplerRequest req, StaplerResponse rsp)
throws IOException, ServletException {
rss(req, rsp, " all builds", new RunList(this));
rss(req, rsp, " all builds", getBuilds());
}
public void doRssFailed(StaplerRequest req, StaplerResponse rsp)
throws IOException, ServletException {
rss(req, rsp, " failed builds", new RunList(this).failureOnly());
rss(req, rsp, " failed builds", getBuilds().failureOnly());
}
private void rss(StaplerRequest req, StaplerResponse rsp, String suffix,
......
......@@ -31,52 +31,56 @@ import hudson.model.Result;
import hudson.model.Run;
import hudson.model.View;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
/**
* {@link List} of {@link Run}s.
* {@link List} of {@link Run}s, sorted in the date order.
*
* @author Kohsuke Kawaguchi
*/
public class RunList extends ArrayList<Run> {
public class RunList<J extends Job<J,R>, R extends Run<J,R>> extends ArrayList<R> {
public RunList() {
}
public RunList(Job<?,?> j) {
public RunList(J j) {
addAll(j.getBuilds());
}
public RunList(View view) {
public RunList(View view) {// this is a type unsafe operation
for (Item item : view.getItems())
for (Job<?,?> j : item.getAllJobs())
addAll(j.getBuilds());
addAll((Collection<R>)j.getBuilds());
Collections.sort(this,Run.ORDER_BY_DATE);
}
public RunList(Collection<? extends Job> jobs) {
for (Job<?,?> j : jobs)
public RunList(Collection<? extends J> jobs) {
for (J j : jobs)
addAll(j.getBuilds());
Collections.sort(this,Run.ORDER_BY_DATE);
}
public static RunList fromRuns(Collection<? extends Run> runs) {
RunList r = new RunList();
r.addAll(runs);
return r;
private RunList(Collection<? extends R> c, boolean hack) {
super(c);
}
public static <J extends Job<J,R>,R extends Run<J,R>>
RunList<J,R> fromRuns(Collection<? extends R> runs) {
return new RunList<J,R>(runs,false);
}
/**
* Filter the list to non-successful builds only.
*/
public RunList failureOnly() {
for (Iterator<Run> itr = iterator(); itr.hasNext();) {
public RunList<J,R> failureOnly() {
for (Iterator<R> itr = iterator(); itr.hasNext();) {
Run r = itr.next();
if(r.getResult()==Result.SUCCESS)
itr.remove();
......@@ -87,8 +91,8 @@ public class RunList extends ArrayList<Run> {
/**
* Filter the list to builds on a single node only
*/
public RunList node(Node node) {
for (Iterator<Run> itr = iterator(); itr.hasNext();) {
public RunList<J,R> node(Node node) {
for (Iterator<R> itr = iterator(); itr.hasNext();) {
Run r = itr.next();
if (!(r instanceof AbstractBuild) || ((AbstractBuild)r).getBuiltOn()!=node) {
itr.remove();
......@@ -100,8 +104,8 @@ public class RunList extends ArrayList<Run> {
/**
* Filter the list to regression builds only.
*/
public RunList regressionOnly() {
for (Iterator<Run> itr = iterator(); itr.hasNext();) {
public RunList<J,R> regressionOnly() {
for (Iterator<R> itr = iterator(); itr.hasNext();) {
Run r = itr.next();
if(!r.getBuildStatusSummary().isWorse)
itr.remove();
......@@ -109,19 +113,52 @@ public class RunList extends ArrayList<Run> {
return this;
}
/**
* Filter the list by timestamp.
*
* {@code s&lt=;e}.
*/
public RunList<J,R> byTimestamp(long start, long end) {
AbstractList<Long> TIMESTAMP_ADAPTER = new AbstractList<Long>() {
public Long get(int index) {
return RunList.this.get(index).getTimeInMillis();
}
public int size() {
return RunList.this.size();
}
};
Comparator<Long> DESCENDING_ORDER = new Comparator<Long>() {
public int compare(Long o1, Long o2) {
if (o1 > o2) return -1;
if (o1 < o2) return +1;
return 0;
}
};
int s = Collections.binarySearch(TIMESTAMP_ADAPTER, start, DESCENDING_ORDER);
if (s<0) s=-(s+1); // min is inclusive
int e = Collections.binarySearch(TIMESTAMP_ADAPTER, end, DESCENDING_ORDER);
if (e<0) e=-(e+1); else e++; // max is exclusive, so the exact match should be excluded
removeRange(s,size());
removeRange(0,e);
return this;
}
/**
* Reduce the size of the list by only leaving relatively new ones.
* This also removes on-going builds, as RSS cannot be used to publish information
* if it changes.
*/
public RunList newBuilds() {
public RunList<J,R> newBuilds() {
GregorianCalendar threshold = new GregorianCalendar();
threshold.add(Calendar.DAY_OF_YEAR,-7);
int count=0;
for (Iterator<Run> itr = iterator(); itr.hasNext();) {
Run r = itr.next();
for (Iterator<R> itr = iterator(); itr.hasNext();) {
R r = itr.next();
if(r.isBuilding()) {
// can't publish on-going builds
itr.remove();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册