Skip to content

Commit

Permalink
refactored BuildStatConfiguration filters and BuildHistorySearchCrite…
Browse files Browse the repository at this point in the history
…ria.jobFilter to BuildSearchCriteria, allowing to share job build result eligibility (in job filtering)
  • Loading branch information
fcamblor committed Sep 23, 2010
1 parent 03b194f commit aedf15a
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 162 deletions.
@@ -0,0 +1,47 @@
package hudson.plugins.global_build_stats;

import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria;
import hudson.plugins.global_build_stats.model.BuildSearchCriteria;
import hudson.plugins.global_build_stats.model.BuildStatConfiguration;
import hudson.plugins.global_build_stats.model.HistoricScale;
import hudson.plugins.global_build_stats.model.YAxisChartType;

import org.kohsuke.stapler.StaplerRequest;

public class FromRequestObjectFactory {

public static BuildHistorySearchCriteria createBuildHistorySearchCriteria(StaplerRequest req){
BuildSearchCriteria criteria = createBuildSearchCriteria(req);
return new BuildHistorySearchCriteria(
Long.parseLong(req.getParameter("start")),
Long.parseLong(req.getParameter("end")),
criteria);
}

public static BuildStatConfiguration createBuildStatConfiguration(String id, StaplerRequest req){
BuildSearchCriteria criteria = createBuildSearchCriteria(req);
return new BuildStatConfiguration(
id,
req.getParameter("title"),
Integer.parseInt(req.getParameter("buildStatWidth")),
Integer.parseInt(req.getParameter("buildStatHeight")),
Integer.parseInt(req.getParameter("historicLength")),
HistoricScale.valueOf(req.getParameter("historicScale")),
YAxisChartType.valueOf(req.getParameter("yAxisChartType")),
Boolean.parseBoolean(req.getParameter("buildStatusesShown")),
Boolean.parseBoolean(req.getParameter("totalBuildTimeShown")),
Boolean.parseBoolean(req.getParameter("averageBuildTimeShown")),
criteria);
}

public static BuildSearchCriteria createBuildSearchCriteria(StaplerRequest req){
BuildSearchCriteria criteria = new BuildSearchCriteria(req.getParameter("jobFilter"),
req.getParameter("nodeFilter"),
Boolean.parseBoolean(req.getParameter("successShown")),
Boolean.parseBoolean(req.getParameter("failuresShown")),
Boolean.parseBoolean(req.getParameter("unstablesShown")),
Boolean.parseBoolean(req.getParameter("abortedShown")),
Boolean.parseBoolean(req.getParameter("notBuildsShown")));
return criteria;
}
}
Expand Up @@ -12,6 +12,7 @@
import hudson.plugins.global_build_stats.business.GlobalBuildStatsBusiness;
import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension;
import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria;
import hudson.plugins.global_build_stats.model.BuildSearchCriteria;
import hudson.plugins.global_build_stats.model.BuildStatChartData;
import hudson.plugins.global_build_stats.model.BuildStatConfiguration;
import hudson.plugins.global_build_stats.model.HistoricScale;
Expand Down Expand Up @@ -87,6 +88,7 @@ public void start() throws Exception {
// XStream compacting aliases...
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.JOB_BUILD_RESULT_CLASS_ALIAS, JobBuildResult.class);
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.BUILD_STAT_CONFIG_CLASS_ALIAS, BuildStatConfiguration.class);
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.BUILD_SEARCH_CRITERIA_CLASS_ALIAS, BuildSearchCriteria.class);
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.HISTORIC_SCALE_CLASS_ALIAS, HistoricScale.class);
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.YAXIS_CHART_TYPE_CLASS_ALIAS, YAxisChartType.class);
Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.YAXIS_CHART_DIMENSION_CLASS_ALIAS, YAxisChartDimension.class);
Expand All @@ -96,11 +98,17 @@ public void start() throws Exception {
Hudson.XSTREAM.aliasField("h", BuildStatConfiguration.class, "buildStatHeight");
Hudson.XSTREAM.aliasField("l", BuildStatConfiguration.class, "historicLength");
Hudson.XSTREAM.aliasField("s", BuildStatConfiguration.class, "historicScale");
Hudson.XSTREAM.aliasField("jf", BuildStatConfiguration.class, "jobFilter");
Hudson.XSTREAM.aliasField("sbr", BuildStatConfiguration.class, "shownBuildResults");
Hudson.XSTREAM.aliasField("yact", BuildStatConfiguration.class, "yAxisChartType");
Hudson.XSTREAM.aliasField("ds", BuildStatConfiguration.class, "dimensionsShown");
Hudson.XSTREAM.aliasField("f", BuildStatConfiguration.class, "buildFilters");
// Deprecated ! Just here for old formats
Hudson.XSTREAM.aliasField("jf", BuildStatConfiguration.class, "jobFilter");
Hudson.XSTREAM.aliasField("sbr", BuildStatConfiguration.class, "shownBuildResults");

Hudson.XSTREAM.aliasField("jf", BuildSearchCriteria.class, "jobFilter");
Hudson.XSTREAM.aliasField("nf", BuildSearchCriteria.class, "nodeFilter");
Hudson.XSTREAM.aliasField("sbr", BuildSearchCriteria.class, "shownBuildResults");

Hudson.XSTREAM.aliasField("r", JobBuildResult.class, "result");
Hudson.XSTREAM.aliasField("n", JobBuildResult.class, "jobName");
Hudson.XSTREAM.aliasField("nb", JobBuildResult.class, "buildNumber");
Expand Down Expand Up @@ -302,7 +310,7 @@ public void doCreateChart(StaplerRequest req, StaplerResponse res) throws Servle
Hudson.getInstance().checkPermission(getRequiredPermission());

// Passing null id since this is a not persisted BuildStatConfiguration
BuildStatConfiguration config = createBuildStatConfig(null, req);
BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(null, req);
JFreeChart chart = business.createChart(config);

ChartUtil.generateGraph(req, res, chart, config.getBuildStatWidth(), config.getBuildStatHeight());
Expand All @@ -317,7 +325,7 @@ public void doCreateChartMap(StaplerRequest req, StaplerResponse res) throws Ser
config = business.searchBuildStatConfigById(buildStatId);
} else {
// Passing null id since this is a not persisted BuildStatConfiguration
config = createBuildStatConfig(null, req);
config = FromRequestObjectFactory.createBuildStatConfiguration(null, req);
}
JFreeChart chart = business.createChart(config);

Expand All @@ -327,8 +335,7 @@ public void doCreateChartMap(StaplerRequest req, StaplerResponse res) throws Ser
public void doBuildHistory(StaplerRequest req, StaplerResponse res) throws ServletException, IOException {
Hudson.getInstance().checkPermission(getRequiredPermission());

BuildHistorySearchCriteria searchCriteria = new BuildHistorySearchCriteria();
req.bindParameters(searchCriteria);
BuildHistorySearchCriteria searchCriteria = FromRequestObjectFactory.createBuildHistorySearchCriteria(req);

List<JobBuildSearchResult> filteredJobBuildResults = business.searchBuilds(searchCriteria);

Expand All @@ -342,7 +349,7 @@ public void doUpdateBuildStatConfiguration(StaplerRequest req, StaplerResponse r

boolean regenerateId = Boolean.valueOf(req.getParameter("regenerateId")).booleanValue();

BuildStatConfiguration config = createBuildStatConfig(req.getParameter("buildStatId"), req);
BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(req.getParameter("buildStatId"), req);
business.updateBuildStatConfiguration(req.getParameter("buildStatId"), config, regenerateId);

String json = JSONObject.fromObject(config).toString();
Expand All @@ -352,7 +359,7 @@ public void doUpdateBuildStatConfiguration(StaplerRequest req, StaplerResponse r
public void doAddBuildStatConfiguration(StaplerRequest req, StaplerResponse res) throws ServletException, IOException {
Hudson.getInstance().checkPermission(getRequiredPermission());

BuildStatConfiguration config = createBuildStatConfig(ModelIdGenerator.INSTANCE.generateIdForClass(BuildStatConfiguration.class), req);
BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(ModelIdGenerator.INSTANCE.generateIdForClass(BuildStatConfiguration.class), req);
business.addBuildStatConfiguration(config);

String json = JSONObject.fromObject(config).toString();
Expand Down Expand Up @@ -411,29 +418,6 @@ public static String getFieldFilterRegex(){
return FieldFilterFactory.REGEX_FIELD_FILTER_LABEL;
}

private BuildStatConfiguration createBuildStatConfig(String id, StaplerRequest req){
// TODO: refactor this using StaplerRequest.bindParameters() with introspection !
return new BuildStatConfiguration(
id,
req.getParameter("title"),
Integer.parseInt(req.getParameter("buildStatWidth")),
Integer.parseInt(req.getParameter("buildStatHeight")),
Integer.parseInt(req.getParameter("historicLength")),
HistoricScale.valueOf(req.getParameter("historicScale")),
req.getParameter("jobFilter"),
req.getParameter("nodeFilter"),
Boolean.parseBoolean(req.getParameter("successShown")),
Boolean.parseBoolean(req.getParameter("failuresShown")),
Boolean.parseBoolean(req.getParameter("unstablesShown")),
Boolean.parseBoolean(req.getParameter("abortedShown")),
Boolean.parseBoolean(req.getParameter("notBuildsShown")),
YAxisChartType.valueOf(req.getParameter("yAxisChartType")),
Boolean.parseBoolean(req.getParameter("buildStatusesShown")),
Boolean.parseBoolean(req.getParameter("totalBuildTimeShown")),
Boolean.parseBoolean(req.getParameter("averageBuildTimeShown"))
);
}

public BuildStatConfiguration[] getBuildStatConfigsArrayed() {
return buildStatConfigs.toArray(new BuildStatConfiguration[]{});
}
Expand Down
Expand Up @@ -7,12 +7,9 @@
import hudson.model.Job;
import hudson.plugins.global_build_stats.GlobalBuildStatsPlugin;
import hudson.plugins.global_build_stats.JobBuildResultFactory;
import hudson.plugins.global_build_stats.FieldFilter;
import hudson.plugins.global_build_stats.FieldFilterFactory;
import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension;
import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension.LegendItemData;
import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria;
import hudson.plugins.global_build_stats.model.BuildResult;
import hudson.plugins.global_build_stats.model.BuildStatConfiguration;
import hudson.plugins.global_build_stats.model.DateRange;
import hudson.plugins.global_build_stats.model.JobBuildResult;
Expand Down Expand Up @@ -118,12 +115,8 @@ public JFreeChart createChart(BuildStatConfiguration config){
public List<JobBuildSearchResult> searchBuilds(BuildHistorySearchCriteria searchCriteria){
List<JobBuildSearchResult> filteredJobBuildResults = new ArrayList<JobBuildSearchResult>();

FieldFilter jobFilter = FieldFilterFactory.createFieldFilter(searchCriteria.jobFilter);
for(JobBuildResult r : plugin.getJobBuildResults()){
if(r.getBuildDate().getTimeInMillis() >= searchCriteria.start
&& r.getBuildDate().getTimeInMillis() < searchCriteria.end
&& jobResultStatusMatchesWith(r.getResult(), searchCriteria)
&& jobFilter.isFieldValueValid(r.getJobName())){
if(searchCriteria.isJobResultEligible(r)){
boolean isJobAccessible = false;
boolean isBuildAccessible = false;

Expand Down Expand Up @@ -220,14 +213,6 @@ public static String escapeAntiSlashes(String value){
}
}

protected static boolean jobResultStatusMatchesWith(BuildResult r, BuildHistorySearchCriteria c){
return (BuildResult.ABORTED.equals(r) && c.abortedShown)
|| (BuildResult.FAILURE.equals(r) && c.failuresShown)
|| (BuildResult.NOT_BUILD.equals(r) && c.notBuildShown)
|| (BuildResult.SUCCESS.equals(r) && c.successShown)
|| (BuildResult.UNSTABLE.equals(r) && c.unstablesShown);
}

private JFreeChart createChart(final BuildStatConfiguration config, List<AbstractBuildStatChartDimension> dimensions, String title) {

final JFreeChart chart = ChartFactory.createStackedAreaChart(title, null, "",
Expand Down Expand Up @@ -324,7 +309,7 @@ public List<AbstractBuildStatChartDimension> createDataSetBuilder(BuildStatConfi

// If no range found : stop the iteration !
if(tickCount != config.getHistoricLength() && currentBuild != null){
if(config.isJobResultEligible(currentBuild)){
if(config.getBuildFilters().isJobResultEligible(currentBuild)){
for(AbstractBuildStatChartDimension dimension : dimensions){
dimension.saveDataForBuild(currentBuild);
}
Expand Down
Expand Up @@ -95,15 +95,19 @@ public String generateURL(CategoryDataset dataset, int row, int column) {
boolean abortedShown=Messages.Build_Results_Statuses_ABORTED().equals(status);
boolean notBuildShown=Messages.Build_Results_Statuses_NOT_BUILD().equals(status);

return new StringBuilder()
.append("buildHistory?jobFilter=").append(config.getJobFilter())
StringBuilder sb = new StringBuilder()
.append("buildHistory?jobFilter=").append(config.getBuildFilters().getJobFilter())
.append("&start=").append(range.getStart().getTimeInMillis())
.append("&end=").append(range.getEnd().getTimeInMillis())
.append("&successShown=").append(successShown)
.append("&failuresShown=").append(failuresShown)
.append("&unstablesShown=").append(unstablesShown)
.append("&abortedShown=").append(abortedShown)
.append("&notBuildShown=").append(notBuildShown).toString();
.append("&notBuildShown=").append(notBuildShown);
if(config.getBuildFilters().getNodeFilter() != null){
sb.append("&nodeFilter=").append(config.getBuildFilters().getNodeFilter());
}
return sb.toString();
}

/* TODO: add tooltip
Expand Down
Expand Up @@ -2,8 +2,18 @@

public class BuildHistorySearchCriteria {

public String jobFilter;
public long start, end;
public boolean successShown, failuresShown, unstablesShown, abortedShown, notBuildShown;
public BuildSearchCriteria buildFilters;

public BuildHistorySearchCriteria(long _start, long _end, BuildSearchCriteria _buildFilters){
this.start = _start;
this.end = _end;
this.buildFilters = _buildFilters;
}

public boolean isJobResultEligible(JobBuildResult result){
return buildFilters.isJobResultEligible(result)
&& (result.getBuildDate().getTimeInMillis() >= this.start)
&& (result.getBuildDate().getTimeInMillis() < this.end);
}
}
@@ -0,0 +1,109 @@
package hudson.plugins.global_build_stats.model;

import hudson.plugins.global_build_stats.FieldFilter;
import hudson.plugins.global_build_stats.FieldFilterFactory;

import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

@ExportedBean
public class BuildSearchCriteria {

private String jobFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL;
transient FieldFilter calculatedJobFilter = null; // For calcul optimizations only
private String nodeFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL;
transient FieldFilter calculatedNodeFilter = null; // For calcul optimizations only
private short shownBuildResults;

public BuildSearchCriteria(String _jobFilter, String _nodeFilter,
boolean _successShown, boolean _failuresShown, boolean _unstablesShown,
boolean _abortedShown, boolean _notBuildsShown){

this.setJobFilter(_jobFilter);
this.setNodeFilter(_nodeFilter);

this.shownBuildResults = 0;
this.shownBuildResults |= _successShown?BuildResult.SUCCESS.code:0;
this.shownBuildResults |= _failuresShown?BuildResult.FAILURE.code:0;
this.shownBuildResults |= _unstablesShown?BuildResult.UNSTABLE.code:0;
this.shownBuildResults |= _abortedShown?BuildResult.ABORTED.code:0;
this.shownBuildResults |= _notBuildsShown?BuildResult.NOT_BUILD.code:0;
}

public boolean isJobResultEligible(JobBuildResult result){
boolean jobBuildEligible = true;

jobBuildEligible &= getCalculatedJobFilter().isFieldValueValid(result.getJobName());
jobBuildEligible &= getCalculatedNodeFilter().isFieldValueValid(result.getNodeName());
jobBuildEligible &= isAbortedShown() || result.getResult().getAbortedCount()!=1;
jobBuildEligible &= isFailuresShown() || result.getResult().getFailureCount()!=1;
jobBuildEligible &= isNotBuildShown() || result.getResult().getNotBuildCount()!=1;
jobBuildEligible &= isSuccessShown() || result.getResult().getSuccessCount()!=1;
jobBuildEligible &= isUnstablesShown() || result.getResult().getUnstableCount()!=1;

return jobBuildEligible;
}

public void setJobFilter(String jobFilter) {
this.jobFilter = jobFilter;
this.calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter);
}

public void setNodeFilter(String nodeFilter) {
this.nodeFilter = nodeFilter;
this.calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter);
}

protected FieldFilter getCalculatedJobFilter(){
// When BuildStatConfiguration is XStream deserialized, the transient calculatedJobFilter field
// will be null !
if(calculatedJobFilter == null){ calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); }
return this.calculatedJobFilter;
}

protected FieldFilter getCalculatedNodeFilter(){
// When BuildStatConfiguration is XStream deserialized, the transient calculatedNodeFilter field
// will be null !
if(calculatedNodeFilter == null){ calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); }
return this.calculatedNodeFilter;
}

@Exported
public boolean isSuccessShown(){
return (shownBuildResults & BuildResult.SUCCESS.code) != 0;
}

@Exported
public boolean isFailuresShown(){
return (shownBuildResults & BuildResult.FAILURE.code) != 0;
}

@Exported
public boolean isUnstablesShown(){
return (shownBuildResults & BuildResult.UNSTABLE.code) != 0;
}

@Exported
public boolean isAbortedShown(){
return (shownBuildResults & BuildResult.ABORTED.code) != 0;
}

@Exported
public boolean isNotBuildShown(){
return (shownBuildResults & BuildResult.NOT_BUILD.code) != 0;
}

@Exported
public String getJobFilter() {
return jobFilter;
}

@Exported
public String getNodeFilter() {
return nodeFilter;
}

public void setShownBuildResults(short shownBuildResults) {
this.shownBuildResults = shownBuildResults;
}
}

0 comments on commit aedf15a

Please sign in to comment.